0
点赞
收藏
分享

微信扫一扫

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标签(任意)

举报

相关推荐

0 条评论