使用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);
}
}
调用次序是:
- Dispatch 的init_PreloadConfiguration方法
- ConfigurationManager的getConfiguration方法
- DefaultConfiguration的reload方法