使用Struts作为mvc模式框架,需要在web.xml 文件中申明org.apache.struts2.dispatcher.FilterDispatcher 这个拦截器作为dispatcher来使用。
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <!-- Extension --> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>*.html</url-pattern> </filter-mapping>
在FilterDispather类中有很多成员对象是依赖annotation注入的,但是奇怪的是FilterDispatcher并不是配置在容器中的,那是如何让容器来将他所依赖的对象注入进来的呢?
原来是通过Filter的init方法,调用dispatcher的init方法,在该方法中会初始化一个container,让后利用该容器将filter所依赖的成员对象注入进来。
public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; dispatcher = createDispatcher(filterConfig); dispatcher.init(); String param = filterConfig.getInitParameter("packages"); String packages = DEFAULT_STATIC_PACKAGES; if (param != null) { packages = param + " " + packages; } this.pathPrefixes = parse(packages); }
在init方法中会调用到com.opensymphony.xwork2.config.impl.DefaultConfiguration 的reload方法,最重要的是container = builder.create(false);这个调用,在这个调用方法中它会将在类中有静态依赖的对象注入
public synchronized void reload(List<ConfigurationProvider> providers) throws ConfigurationException { packageContexts.clear(); loadedFileNames.clear(); ContainerProperties props = new ContainerProperties(); ContainerBuilder builder = new ContainerBuilder(); for (ConfigurationProvider configurationProvider : providers) { configurationProvider.init(this); configurationProvider.register(builder, props); } props.setConstants(builder); builder.factory(Configuration.class, new Factory<Configuration>() { public Configuration create(Context context) throws Exception { return DefaultConfiguration.this; } }); try { // Set the object factory for the purposes of factory creation ObjectFactory.setObjectFactory(new ObjectFactory()); container = builder.create(false); objectFactory = container.getInstance(ObjectFactory.class); ObjectFactory.setObjectFactory(objectFactory); for (ConfigurationProvider configurationProvider : providers) { container.inject(configurationProvider); configurationProvider.loadPackages(); } rebuildRuntimeConfiguration(); } finally { ObjectFactory.setObjectFactory(null); } }
调用次序是: