Strust2 internal Container 如何将spring容器中的bean注入到静态类中的?
在struts-plugin.xml这个文件中的配置信息,如下:
<bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="xml" class="org.apache.struts2.rest.handler.XStreamHandler" /> <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="json" class="org.apache.struts2.rest.handler.JsonLibHandler" /> <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="html" class="org.apache.struts2.rest.handler.HtmlHandler" /> <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="x-www-form-urlencoded" class="org.apache.struts2.rest.handler.FormUrlEncodedHandler" /> <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="multipart/form-data" class="org.apache.struts2.rest.handler.MultipartFormDataHandler" />
type一般是一组bean的接口,而class 是每个bean的实现类,而name则是这些bean的具体名字,这个名字起到了这个配置项目的identity作用。
在java代码中当在上下文中拿到container对象之后,可以通过如下方式来操作配置在struts2配置文件中的bean:
Set<String> names = container.getInstanceNames(ContentTypeHandler.class);
通过接口类,找到容器中所有实现了这个接口的bean
container.getInstance(ContentTypeHandler.class, name);
参数name就是 bean配置项目的name属性,在配置文件中配置的bean应该都是单例的。
有一个问题一直不太理解,在struts-default.xml文件中定义的一个类型的几个实例对象,如下:
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts" class="org.apache.struts2.dispatcher.mapper.DefaultActionMapper" /> <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="composite" class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" /> <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful" class="org.apache.struts2.dispatcher.mapper.RestfulActionMapper" /> <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful2" class="org.apache.struts2.dispatcher.mapper.Restful2ActionMapper" />
同样是org.apache.struts2.dispatcher.mapper.ActionMapper 这个接口,但是有四种不同的实现,但是在org.apache.struts2.dispatcher.FilterDispatcher
/** * Modify ActionMapper instance. * @param mapper New instance */ @Inject public void setActionMapper(ActionMapper mapper) { actionMapper = mapper; }
这个类中的方法,那在运行期,struts2容器到底会将那个版本的实现注入进来呢?
经过试验如果在strust.xml 中定义两个bean实现相同的接口:
<bean name="testImpl1" class="com.koubei.profile.test.TestImpl1" type="com.koubei.profile.test.ITestInterface"/> <bean name="default" class="com.koubei.profile.test.TestImpl2" type="com.koubei.profile.test.ITestInterface"/>
在Action中实现设置一个函数:
@Inject public void setTestInterface(ITestInterface testInterface) { this.testInterface = testInterface; }
会把名字为name为default的实现版本注入到action中,这样问题又来了,在默认的struts-default.xml文件中有配置的bean的name并不是以default开头的,那他们是按照怎么一个规则被注入到别的bean中的呢?
这个可以查看一下 struts.properties 配置文件 http://struts.apache.org/2.0.11/docs/strutsproperties.html