zoukankan      html  css  js  c++  java
  • s2dao 入门知识2

    nclude标签的path属性被用来指定想要引入的S2Container定义文件的路径。详细情况请参照include标签。
    组件的检索顺序,先是在自身注册的文件中寻找组件,没有找到所需组件的情况下,将按照include的顺序在子定义文件中查找注册到S2Container中的组件,最先找到的那个组件将被返回。
    <components>
        <include path="aaa.dicon"/>
        <include path="bbb.dicon"/>
        <component class="example.container.Foo" />
    </components>
    命名空间

    组件的定义被分割的情况下,为了不让复数个组件的定义名称发生冲突,可以用components标签的namespace属性指定命名空间。
    foo.dicon
    <components namespace="foo">
        <component name="aaa" .../>
        <component name="bbb" ...>
            <arg>aaa</arg>
        </component>
    </components>
    bar.dicon
    <components namespace="bar">
        <include path="foo.dicon"/>
        <component name="aaa" .../>
        <component name="bbb" ...>
            <arg>aaa</arg>
        </component>
        <component name="ccc" ...>
            <arg>foo.aaa</arg>
        </component>
    </components>
    app.dicon
    <components>
        <include path="bar.dicon"/>
    </components>

    在同一个组件定义文件中可以不需要指定命名空间而调用组件。调用其它S2Container文件中定义的组件时,要在组件名前加上命名空间。foo.aaa 和 bar.aaa 虽然有相同名称的组件,但是因为命名空间的不同,就被认为是不同的组件。
    实例(instance)管理

    在S2Container中,怎么样对实例进行管理,这个设定是用component标签的instance属性。
    instance属性 说明
    singleton(default) 不论S2Container.getComponent()被调用多少次都返回同一个实例。
    prototype S2Container.getComponent()每次被调用的时候都返回一个新的实例。
    request 对应每一个请求(request)做成一个实例。用name属性中指定的名称,组件被容纳在请求中。使用request的场合下需要设定S2ContainerFilter。
    session 对应每一个session做成一个实例。用name属性中指定的名称,组件被容纳在session中。使用session的场合下需要设定S2ContainerFilter。
    application 使用Servlet的场合下,对应每一个ServletContext做成一个实例。用name属性中指定的名称,组件被容纳在ServletContext中。使用application的场合下需要设定S2ContainerFilter。
    outer 组件的实例在S2Container之外作成,从而仅仅行使Dependency Injection的功能。Aspect、构造函数注入不能适用。

    生存周期

    使用initMethod 和 destroyMethod组件的生存周期也可以用容器来管理。在S2Container的开始时用(S2Container.init())调用 initMethod标签中指定的方法,S2Container结束时用(S2Container.destroy())调用destroyMethod 标签中指定的方法。initMethod将按照容器中注册的组件的顺序来执行组件,destroyMethod则按照相反的顺序去执行。instance 属性是singleton之外的情况下,指定了destroyMethod也会被忽视。java.util.HashMap#put()方法中初始化(给 aaa赋值为111)?结束处理(给aaa赋值为null)的设定,向下面那样。
    <components namespace="bar">
        <component name="map" class="java.util.HashMap">
            <initMethod name="put">
                <arg>"aaa"</arg>
                <arg>111</arg>
            </initMethod>
            <destroyMethod name="put">
                <arg>"aaa"</arg>
                <arg>null</arg>
            </destroyMethod>
        </component>
    </components>
    自动绑定

    组件间的依存关系,类型是interface的场合时,将由容器来自动解决。这是在S2Container被默认的,指定component标签的autoBinding属性可以进行更加细致的控制。
    autoBinding 说明
    auto(default) 适用于构造函数和属性变量的自动绑定。
    constructor 适用于构造函数的自动绑定。
    property 适用于属性变量的自动绑定。
    none 只能对构造函数、属性变量进行手动绑定。

    构造函数的自动绑定规则如下所示。
    明确指定了构造函数的参数的情况下,自动绑定将不再适用。
    不属于上述情况,如果是定义了没有参数的默认的构造函数的话,对于这个构造函数,自动绑定也不适用。
    不属于上述情况,参数的类型全是interface并且参数数目最多的构造函数将被使用。 这样,对于从容器中取得参数类型的实装组件,自动绑定是适用的。
    如果不是以上情况,自动绑定将不适用。

    属性变量的自动绑定规则如下。
    明确指定了属性变量的情况下,自动绑定将不适用。
    不属于上述情况,如果在容器的注册组件中存在着可以代入属性变量中的同名组件,自动绑定将适用于该组件。
    不属于上述情况,属性变量的类型是interface并且该属性类型的实装组件在容器中注册了的话,自动绑定是适用的。
    如果不是以上情况,自动绑定将不适用。

    用property标签的bindingType属性,可以更加细致的控制属性变量。
    bindingType 说明
    must 自动绑定不适用的情况下?将会发生例外。
    should(default) 自动绑定不适用的情况下,将发出警告通知。
    may 自动绑定不适用的情况下,什么都不发生。
    none autoBinding的属性虽然是auto、property情况下,自动绑定也不适用。


    在组件中利用S2Container

    不想让组件依存于S2Container的情况下,根据组件的具体情况,在组件中需要调用S2Container的方法,这样的场合也许会存在。 S2Container自身也以container的名称,自我注册了。所以可以在arg,property标签的正文中指定container,从而取 得容器的实例。还有,S2Container类型的setter方法定义好了后也可以做自动绑定的设定。用arg,property标签指定 container的情况下,向下面这样进行。
    <components>
        <component class="examples.dicon.BarImpl">
            <arg>container</arg>
        </component>

        <component class="examples.dicon.FooImpl">
            <property name="foo">container</property>
        </component>
    </components>
    S2ContainerServlet

    到此为止,在Java application中,是用明确表示的方法做成S2Container的,Web application的情况下,由谁来作成S2Container呢?为了达到这个目的,准备了以下的类。
    org.seasar.framework.container.servlet#S2ContainerServlet

    为了使用S2ContainerServlet,在web.xml中记述如下项目。
    <servlet>
        <servlet-name>s2servlet</servlet-name>
        <servlet-class>org.seasar.framework.container.servlet.S2ContainerServlet</servlet-class>
        <init-param>
            <param-name>configPath</param-name>
            <param-value>app.dicon</param-value>
        </init-param>
        <init-param>
            <param-name>debug</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>s2servlet</servlet-name>
        <url-pattern>/s2servlet</url-pattern>
    </servlet-mapping>

    用configPath来指定作为根的S2Container的定义路径。定义文件将放在WEB-INF/classes中。对于 S2ContainerServlet,为了比其它的servlet更早的起动,请做load-on-startup标签的调整。 S2ContainerServlet起动之后,可以用如下的方法函数取得S2Container的实例。
    org.seasar.framework.container.factory.SingletonS2ContainerFactory#getContainer()

    另外,S2Container的生命周期和S2ContainerServlet是连动的。debug变量被设为true的话,按照以下的方法,可以将运行中的S2Container再次起动。xxx是Web application的context名。
    http://localhost:8080/xxx/s2servlet?command=restart
               

    在使用了S2ContainerServlet的情况下,ServletContext将会作为一个组件可以用servletContext的名字来访问。
    app.dicon的角色

    根的S2Container的定义文件,按照惯例用app.dicon的名称。通常放在WEB-INF/classes中就好了。
    AOP的适用

    在组件中AOP的适用情况也可以被设定。比如,想要在ArrayList中设定TraceInterceptor使用的情况下需要象下面这样做。
    <components>
        <component name="traceInterceptor"
                   class="org.seasar.framework.aop.interceptors.TraceInterceptor"/>
        <component class="java.util.ArrayList">
            <aspect>traceInterceptor</aspect>
        </component>
        <component class="java.util.Date">
            <arg>0</arg>
            <aspect pointcut="getTime, hashCode">traceInterceptor</aspect>
        </component>
    </components>

    aspect标签的正文中指定Interceptor的名字。pointcut的属性中可以用逗号做分隔符指定AOP对象的方法的名字。 pointcut的属性没有被指定的情况下,组件将把实装的interface的所有方法函数作为AOP的对象。方法函数的名称指定也可以用正则表达式 (JDK1.4のregex)。这样的定义例子如下。
    private static final String PATH =
        "examples/dicon/Aop.dicon";
    S2Container container = S2ContainerFactory.create(PATH);
    List list = (List) container.getComponent(List.class);
    list.size();
    Date date = (Date) container.getComponent(Date.class);
    date.getTime();
    date.hashCode();
    date.toString();

    执行结果。
    BEGIN java.util.ArrayList#size()
    END java.util.ArrayList#size() : 0
    BEGIN java.util.Date#getTime()
    END java.util.Date#getTime() : 0
    BEGIN java.util.Date#hashCode()
    BEGIN java.util.Date#getTime()
    END java.util.Date#getTime() : 0
    END java.util.Date#hashCode() : 0
    BEGIN java.util.Date#getTime()
    END java.util.Date#getTime() : 0

    组件中也可以设定InterType的适用情况。比如,在Hoge中设定PropertyInterType的适用情况如下进行。
    <components>
        <include path="aop.dicon"/>
        <component class="examples.Hoge">
            <interType>aop.propertyInterType</aspect>
        </component>
    </components>

    在interType标签的正文中指定InterType的名称。
    Meta数据

    在components、component、arg、property标签中也可以指定Meta数据。meta标签将作为需要指定Meta数据的标签的字标签来指定Meta数据。例如,想要在components标签中指定Meta数据的情况时,象下面一样设定。
    <components>
        <meta name="aaa">111</meta>
    </components>
    request的自动绑定

    对于组件来说,也可以进行HttpServletRequest的自动绑定。为了实现这个目的,在组件中,定义了 setRequest(HttpServletRequest request)方法。这样的话,S2Container就自动得设定了request。还有,需要象下面这样在web.xml中进行Filter的定 义。
    <web-app>
        <filter>
            <filter-name>s2filter</filter-name>
            <filter-class>org.seasar.framework.container.filter.S2ContainerFilter</filter-class>
        </filter>

        <filter-mapping>
            <filter-name>s2filter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    </web-app>

    同样地对HttpServletResponse、HttpSession、ServletContext也是只要定义了setter方法,就可以 自动绑定了。而且,使用了S2ContainerFilter的话,HttpServletRequest、HttpServletResponse、 HttpSession、ServletContext就可以各自用request、response、session、application的名字来 做为组件被自由访问了。
    组件的自动注册

    根据自动绑定的原理,DI的设定几乎可以做近乎全部的自动化。 使用备注码就有可能进行更加细致的设定。 更进一步、对组件的注册也进行自动化的话,就可以称为组件的自动注册机能了。
    org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister

    是从文件系统中将类检索出来对组件进行自动注册的组件。
    属性 说明
    instanceDef 在自动注册的组件中指定适用的InstanceDef。用XML指定的场合下,
    @org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST
    这样来指定。
    autoBindingDef 在自动注册的组件中指定适用的AutoBindingDef。用XML指定的场合下,
    @org.seasar.framework.container.assembler.AutoBindingDefFactory@NONE
    这样来指定。
    autoNaming 可以根据类名来自动决定组件名的组件。需要实装 org.seasar.framework.container.autoregister.AutoNaming interface。默认状态下,使用 org.seasar.framework.container.autoregister.DefaultAutoNaming类的实例。

    方法 说明
    addClassPattern 将想要自动注册的类模式注册。最开始的一个参数是组件所在包的名字。子包也能被以回归的方式进行检索。第二个参数是类的名字。可以使用正则表达式。也可以用“,”分隔做复数个设定。
    addIgnoreClassPattern 将不想自动注册的类模式注册。最开始的一个参数是组件所在包的名字。子包也能被以回归的方式进行检索。第二个参数是类的名字。可以使用正则表达式。也可以用“,”分隔做复数个设定。

    org.seasar.framework.container.autoregister.JarComponentAutoRegister

    从Jar文件中检索类自动注册组件的组件。
    属性 说明
    jarFileNames 指定设定对象的jar文件名。可以使用正则表达式。但是能包含后缀。指定复数个对象的场合下,用“,”做分割符。例如,myapp.*, yourapp.*这样。
    referenceClass 用这个属性指定的类所属的jar文件的父路径为基础路径(例如,WEB-INF/lib)。默认的是org.aopalliance.intercept.MethodInterceptor.class。
    instanceDef 适用于自动注册的组件的InstanceDef的指定。在XML中如下,
    @org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST
    这样指定。
    autoBindingDef 适用于自动注册的组件的AutoBindingDef的指定。在XML中如下,
    @org.seasar.framework.container.assembler.AutoBindingDefFactory@NONE
    这样指定。
    autoNaming 根据类名自动决定组件的名称的组件。需要对 org.seasar.framework.container.autoregister.AutoNaming interface 进行实装。默认的情况下是 org.seasar.framework.container.autoregister.DefaultAutoNaming类的实例。

    方法 说明
    addClassPattern 将想要自动注册的类模式注册。最开始的一个参数是组件所在包的名字。子包也能被以回归的方式进行检索。第二个参数是类的名字。可以使用正则表达式。也可以用“,”分隔做复数个设定。
    addIgnoreClassPattern 将不想自动注册的类模式注册。最开始的一个参数是组件所在包的名字。子包也能被以回归的方式进行检索。第二个参数是类的名字。可以使用正则表达式。也可以用“,”分隔做复数个设定。

    org.seasar.framework.container.autoregister.ComponentAutoRegister

    将类从文件系统或者Jar文件中检索出来并将组件自动注册的组件。
    属性 说明
    instanceDef 适用于自动注册的组件的InstanceDef的指定。在XML中如下,@org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST这样指定。
    autoBindingDef 适用于自动注册的组件的AutoBindingDef的指定。在XML中如下,
    @org.seasar.framework.container.assembler.AutoBindingDefFactory@NONE
    这样指定。
    autoNaming 从类的名称来自动决定组件的名称的组件。需要对 org.seasar.framework.container.autoregister.AutoNaming instance进行实装。默认的是 org.seasar.framework.container.autoregister.DefaultAutoNaming类的实例。

    方法 说明
    addReferenceClass 以这个方法所指定的类所存在的路径或者Jar文件为基点对类进行检索。
    addClassPattern 将想要自动注册的类模式注册。最开始的一个参数是组件所在包的名字。子包也能被以回归的方式进行检索。第二个参数是类的名字。可以使用正则表达式。也可以用“,”分隔做复数个设定。
    addIgnoreClassPattern 将不想 自动注册的类模式注册。最开始的一个参数是组件所在包的名字。子包也能被以回归的方式进行检索。第二个参数是类的名字。可以使用正则表达式。也可以用“,”分隔做复数个设定。


    AutoNaming

    根据AutoNaming来控制组件名称。
    org.seasar.framework.container.autoregister.DefaultAutoNaming

    从类的完整合法名称中将类的包的那部分名称去掉,如果结尾是Impl或者Bean也要去掉,之后将开头的字母变成小写做为组件名称来设定。 例如,aaa.HogeImpl类的情况下,组件的名称就成了hoge。
    属性 说明
    decapitalize 组件名的开头字母为小写的情况下指定为true。默认值是true。

    方法 说明
    setCustomizedName 不依从于默认的规则对类进行注册。第一个参数是类的完整合法名。第二个参数是组件的名称。
    addIgnoreClassSuffix 指定从类名的尾端消除的部分。注册默认值为Impl以及Bean。
    addReplaceRule 根据正则表达式追加替换规则。第一个参数为正则表达式。第二个参数为向要替换的字符串。
    clearReplaceRule 用setCustomizedName、addIgnoreClassSuffix、addReplaceRule将注册的变换规则清零。作为默认值被注册的Impl和Bean也被清零。

    org.seasar.framework.container.autoregister.QualifiedAutoNaming

    将包的名字或者是一部分类的合法名做为组件名称的设定。从类的完整合法名的最后把Impl或者Bean去掉,开头字母小写,分隔点后紧接着的字母变成大写并取掉分隔点,将这个新的单词设定为组件的名称。
    可以将包的开头的不要的部分做消除指定。
    例如,aaa.bbb.ccc.ddd.HogeImpl类的情况下,将开头的aaa.bbb做消除指定的情况下组件的名称为,cccDddHogeになります。
    属性 说明
    decapitalize 组件名的开头字母为小写的情况下指定为true。默认值是true。

    方法 说明
    setCustomizedName 遵从默认的规则来注册类。第一个参数是类的完整合法名。 第二个参数是组件的名称。
    addIgnorePackagePrefix 从包名称的开头开始指定消除的部分。
    addIgnoreClassSuffix 类名称的最末尾开始指定消除的部分。默认地将Impl和Bean注册。
    addReplaceRule 根据正则表达式追加替换规则。第一个参数为正则表达式。第二个参数是替换的新字符串。
    clearReplaceRule 将setCustomizedName、 addIgnorePackagePrefix、 addIgnoreClassSuffix、 addReplaceRule注册的替换规则清除。默认注册的Impl以及Bean也将被清除。


    <component
    class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
        <property name="autoNaming">
            <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming">
                <initMethod name="setCustomizedName">
                    <arg>"examples.di.impl.HogeImpl"</arg>
                    <arg>"hoge2"</arg>
                </initMethod>
            </component>
        </property>
        <initMethod name="addClassPattern">
            <arg>"examples.di.impl"</arg>
            <arg>".*Impl"</arg>
        </initMethod>
    </component>
    <component class="org.seasar.framework.container.autoregister.JarComponentAutoRegister">
        <property name="referenceClass">
            @junit.framework.TestSuite@class
        </property>
        <property name="jarFileNames">"junit.*"</property>
        <initMethod name="addClassPattern">
            <arg>"junit.framework"</arg>
            <arg>"TestSuite"</arg>
        </initMethod>
    </component>
    <component class="org.seasar.framework.container.autoregister.ComponentAutoRegister">
        <initMethod name="addReferenceClass">
            <arg>@aaa.bbb.ccc.ddd.HogeImpl@class</arg>
        </initMethod>
        <initMethod name="addClassPattern">
            <arg>"aaa.bbb"</arg>
            <arg>".*Impl"</arg>
        </initMethod>
    </component>
    AOP的自动注册

    根据组件的自动注册规则,组件的注册可以做到自动化。进一步,AOP的注册也可以做到自动化,这就是AOP的自动注册机能。

    和组件的自动注册功能组和使用的场合下,必须在组件的自动注册设定之后,作AOP的自动注册的设定。对于适用于使用AOP的组件的记述,必须在AOP的自动注册设定之后进行。
    <components>
        <!-- 1.组件的自动注册 -->
        <component class="org.seasar.framework.container.autoregister.ComponentAutoRegister">
            ...
        </component>

        <!-- 2.AOP的自动注册 -->
        <component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
            ...
        </component>

        <!-- 3.其它的组件 -->
        <component class="...">
            ...
        </component>
        ...
    <components>
    org.seasar.framework.container.autoregister.AspectAutoRegister

    通过指定类名的模式来进行AOP的自动注册的组件。
    属性 说明
    interceptor 指定interceptor。想要指定复数个interceptor的场合下,请使用InterceptorChain。
    pointcut 适于使用interceptor的方法用逗号分隔开进行指定。不指定pointcut的情况下,实装组件的interface的所有方法都做为interceptor的对象。对于方法名称也可以使用正则表达式(JDK1.4のregex)来指定。

    方法 说明
    addClassPattern 将想要自动注册的类的模式注册。第一个参数是组件的包的名。子包也可以用回归的方法检索。第二个参数是类名。可以使用正则表达式。用“,”分隔可以做复数个记述。
    addIgnoreClassPattern 将不想自动注册的类模式注册。第一个参数是组件的包的名。子包也可以用回归的方法检索。第二个参数是类名。可以使用正则表达式。用“,”分隔可以做复数个记述。



    <include path="aop.dicon"/>
    ...
    <component
    class="org.seasar.framework.container.autoregister.AspectAutoRegister">
        <property name="interceptor">aop.traceInterceptor</property>
        <initMethod name="addClassPattern">
            <arg>"examples.di.impl"</arg>
            <arg>".*Impl"</arg>
        </initMethod>
    </component>
    org.seasar.framework.container.autoregister.InterfaceAspectAutoRegister

    针对某个interface的实装类进行AOP的自动注册的组件。
    属性 说明
    interceptor 指定interceptor。想要指定复数个interceptor的场合下,请使用InterceptorChain。
    targetInterface 针对某一指定的interface的实装组件,使用AOP。


    <include path="aop.dicon"/>
    ...
    <component
    class="org.seasar.framework.container.autoregister.InterfaceAspectAutoRegister">
        <property name="interceptor">aop.traceInterceptor</property>
        <property name="targetInterface">@examples.Greeing@class</property>
    </component>
    META的自动注册

    META信息也可以自动注册。

    同组件的自动注册相组合使用的场合下,必须在组件的自动注册设定之后,做META的自动注册的设定记述。 调用META信息的组件必须在META自动注册的设定之后记述。
    <components>
        <!-- 1.组件的自动注册 -->
        <component class="org.seasar.framework.container.autoregister.ComponentAutoRegister">
            ...
        </component>

        <!-- 2.META的自动注册 -->
        <component class="org.seasar.framework.container.autoregister.MetaAutoRegister">
            ...
        </component>

        <!-- 3.其它的组件 -->
        <component class="...">
            ...
        </component>
        ...
    <components>
    org.seasar.framework.container.autoregister.MetaAutoRegister

    通过指定类名的模式来做META自动注册的组件。
    被自动注册的META数据,将做为在这个组件自身的定义中一个叫做autoRegister的META数据的子数据来记述。
    方法 说明
    addClassPattern 将想要自动注册的类模式注册。第一个参数是组件所在包的名字。子包也将被用回归的方式所检索。第二个参数是类名。可以使用正则表达式。用“,”做分隔符号,可以做复数个记述。
    addIgnoreClassPattern 将不想自动注册的类模式注册。第一个参数是组件所在包的名字。子包也将被用回归的方式所检索。第二个参数是类名。可以使用正则表达式。用“,”做分隔符号,可以做复数个记述。


    <component
    class="org.seasar.framework.container.autoregister.MetaAutoRegister">
        <meta name="autoRegister">
            <meta name="hoge"</meta>
        </meta>
        <initMethod name="addClassPattern">
            <arg>"examples.di.impl"</arg>
            <arg>".*Impl"</arg>
        </initMethod>
    </component>

    本例中、叫做hoge的META数据自动地注册到其它的组件定义中。
    Hotswap

    一直以来,更改了源代码并重新编译之后的场合,想要测试编译后的机能,必须让应用程序(确切地说是ClassLoader)再起动。在应用程序服务器上,进行程序再起动将非常花时间。 “真烦人”这样想的人很多不是吗。

    在Seasar2中,应用程序在运行中,即使类文件替换了,也可以即刻测试的Hotswap机能得以实现。这样就让我们从那种“心情烦躁”中解放出来了。无须花费多余的时间使得出产率得以提高。这样的好东西,不想试一试吗?
    Greeting.java
    package examples.hotswap;

    public interface Greeting {

        String greet();
    }
    GreetingImpl.java
    package examples.hotswap.impl;

    import examples.hotswap.Greeting;

    public class GreetingImpl implements Greeting {

        public String greet() {
            return "Hello";
        }
    }
    hotswap.dicon
    <components>
        <component class="examples.hotswap.impl.GreetingImpl"/>
    </components>

    到此为止,并没有什么特别的变化。关键点从此开始。 使用s2container.dicon,切换成hotswap模式。
    s2container.dicon
    <components>
        <component
          class="org.seasar.framework.container.factory.S2ContainerFactory$DefaultProvider">
            <property name="hotswapMode">true</property>
        </component>
    </components>

    把s2container.dicon根据class path放到根路径下的话,就能被自动识别到。也可以使用S2ContainerFactory#configure()明确地指定。
    GreetingMain.dicon
    package examples.hotswap.main;

    import org.seasar.framework.container.S2Container;
    import org.seasar.framework.container.factory.S2ContainerFactory;

    import examples.hotswap.Greeting;

    public class GreetingMain {

        private static final String CONFIGURE_PATH =
            "examples/hotswap/dicon/s2container.dicon";

        private static final String PATH =
            "examples/hotswap/dicon/hotswap.dicon";

        public static void main(String[] args) throws Exception {
            S2ContainerFactory.configure(CONFIGURE_PATH);
            S2Container container = S2ContainerFactory.create(PATH);
            System.out.println("hotswapMode:" + container.isHotswapMode());
            container.init();
            try {
                Greeting greeting = (Greeting) container
                        .getComponent(Greeting.class);
                System.out.println(greeting.greet());
                System.out.println("Let's modify GreetingImpl, then press ENTER.");
                System.in.read();
                System.out.println("after modify");
                System.out.println(greeting.greet());
            } finally {
                container.destroy();
            }
        }
    }

    为了使用hotswap,有必要调用S2Container#init()。 执行了的话"Hello"表示出来后,程序就停止了,所以将GreetingImpl#greet()修改并编译使之表示"Hello2"。这之后,请将 文字终端显示窗口调成聚焦状态并按下ENTER键。虽然是用同一个instance也没有关系,class文件被替换了的事实可以很容易的被测知。这个是 实例模式为singleton的场合下的例子,实例模式为prototype的场合下,类将在调用S2Container#getComponent() 的时刻被置换。
    执行结果
    hotswapMode:true
    Hello
    Let's modify GreetingImpl, then press ENTER.

    after modify
    Hello2

    为了使用hotswap,组件提供了interface,组件的利用者方面,必须通过interface来利用组件。 实例模式为request、session的情况下,对于一个组件不能被其它的组件调用的场合来说,没有interface也可以利用hotswap。
    S2Container标签参考
    DOCTYPE

    DOCTYPE要在XML声明之后指定。请象下面那样指定。
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.3//EN"
    "http://www.seasar.org/dtd/components23.dtd">
    <components>
        <component name="hello" class="examples.dicon.HelloConstructorInjection">
            <arg>"Hello World!"</arg>
        </component>
    </components>
    components标签(必须)

    成为了根标签。
    namespace属性(任意)

    可以指定命名空间。做为Java的标识语来使用
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.3//EN"
    "http://www.seasar.org/dtd/components23.dtd">
    <components namespace="hoge">
        ...
    </components>
    include标签(任意)

  • 相关阅读:
    JavaScript Hoisting
    关于性能工具
    JavaScript 新旧替换五:函数嵌套
    JavaScript 新旧替换四:继承
    JavaScript 新旧替换三:参数转换
    JavaScript 新旧替换二:赋值和取值
    test
    这么多数组方法,你掌握了么?
    问问自己,你真的会用防抖和节流么????
    防抖、节流、闭包的真谛所在
  • 原文地址:https://www.cnblogs.com/likwo/p/1760456.html
Copyright © 2011-2022 走看看