前面说过Struts2的入口是个Filter 那么我们来看在init方法中他初始化的容器
Xml代码
< filter >
< filter-name > struts2 </ filter-name >
< filter-class > org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </ filter-class >
</ filter >
< filter-mapping >
< filter-name > struts2 </ filter-name >
< url-pattern > /* </ url-pattern >
</ filter-mapping >
StrutsPrepareAndExecuteFilter与普通的Filter并无区别,方法除继承自Filter外,仅有一个回调方法,第三部分我 们将按照Filter方法调用顺序,由init—>doFilter—>destroy顺序地分析源码。
1、init方法
init是Filter第一个运行的方法,我们看下struts2的核心Filter在调用init方法初始化时做哪些工作:
java代码:
public void init(FilterConfig filterConfig) throws ServletException {
InitOperations init = new InitOperations(); //拦截器配置参数FilterConfig 是配置文件中filter参数 包括Filter的名字 Filter的全类名
try {
//封装filterConfig,其中有个主要方法getInitParameterNames将参数名字以String格式存储在List中
FilterHostConfig config = new FilterHostConfig(filterConfig);
// 初始化struts内部日志
init.initLogging(config);
//<strong>创建dispatcher ,并初始化,这部分下面我们重点分析,初始化时加载那些资源</strong>
Dispatcher dispatcher = init.initDispatcher(config);
init.initStaticContentLoader(config, dispatcher);
//初始化类属性:prepare 、execute 这两个类是为了处理http请求做准备
prepare = new PrepareOperations(dispatcher);
execute = new ExecuteOperations(dispatcher); <p class="p1"><span class="s1"><span style="white-space:pre"> </span> //哪些请求是被过滤掉的, 不执行拦截器</span></p> this .excludedPatterns = init.buildExcludedPatternsList(dispatcher);
//回调空的postInit方法
postInit(dispatcher, filterConfig);
} finally {
init.cleanup();
}
}
首先看下FilterHostConfig ,源码如下:
public class FilterHostConfig implements HostConfig {
private FilterConfig config;
/**
*构造函数
*/
public FilterHostConfig(FilterConfig config) {
this .config = config;
}
/**
* 根据init-param配置的param-name获取param-value的值
*/
public String getInitParameter(String key) {
return config.getInitParameter(key);
}
/**
* 返回初始化参数名的List
*/
public Iterator<String> getInitParameterNames() {
return MakeIterator.convert(config.getInitParameterNames());
}
public ServletContext getServletContext() {
return config.getServletContext();
}
}
只有短短的几行代码,getInitParameterNames是这个类的核心,将Filter初始化参数名称由枚举类型转为Iterator。此类的主要作为是对filterConfig 封装。
重点来了,创建并初始化Dispatcher
public Dispatcher initDispatcher( HostConfig filterConfig ) {
Dispatcher dispatcher = createDispatcher(filterConfig);
dispatcher.init();
return dispatcher;
}
创建Dispatcher,会读取 filterConfig 中的配置信息,将配置信息解析出来,封装成为一个Map,然后根据servlet上下文和参数Map构造Dispatcher :
private Dispatcher createDispatcher( HostConfig filterConfig ) {
Map<String, String> params = new HashMap<String, String>();
for ( Iterator e = filterConfig.getInitParameterNames(); e.hasNext(); ) {
String name = (String) e.next();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
} //初始化一个Dispatcher 参数为Servlet上下文 和filterConfig封装成的Map
return new Dispatcher(filterConfig.getServletContext(), params);
}
Dispatcher初始化,加载struts2的相关配置文件,将按照顺序逐一加载:default.properties,struts-default.xml,struts-plugin.xml,struts.xml,……
/**
*初始化过程中依次加载如下配置文件
*/
public void init() {
if (configurationManager == null ) {
configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
}
try { init_FileManager();
//加载org/apache/struts2/default.properties
init_DefaultProperties(); // [1]
//加载struts-default.xml,struts-plugin.xml,struts.xml
init_TraditionalXmlConfigurations(); // [2]
init_LegacyStrutsProperties(); // [3]
//用户自己实现的ConfigurationProviders类
init_CustomConfigurationProviders(); // [5]
//Filter的初始化参数
init_FilterInitParameters() ; // [6]
init_AliasStandardObjects() ; // [7]
Container container = init_PreloadConfiguration();
container.inject(this );
init_CheckConfigurationReloading(container);
init_CheckWebLogicWorkaround(container);
if (!dispatcherListeners.isEmpty()) {
for (DispatcherListener l : dispatcherListeners) {
l.dispatcherInitialized(this );
}
}
} catch (Exception ex) {
if (LOG.isErrorEnabled())
LOG.error("Dispatcher initialization failed" , ex);
throw new StrutsException(ex);
}
}
初始化default.properties,具体的初始化操作在DefaultPropertiesProvider类中
private void init_DefaultProperties() {
configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
}
下面我们看下DefaultPropertiesProvider类源码:
public void register(ContainerBuilder builder, LocatableProperties props)
throws ConfigurationException {
Settings defaultSettings = null ;
try {
defaultSettings = new PropertiesSettings( "org/apache/struts2/default" );
} catch (Exception e) {
throw new ConfigurationException( "Could not find or error in org/apache/struts2/default.properties" , e);
}
loadSettings(props, defaultSettings);
}
初始化辅助类 InitOperations------>封装FilterHostConfig------>初始化Struts2日志类------->初始化Dispatcher(会读取 filterConfig 中的配置信息,将配置信息解析出来,封装成为一个Map,然后根据servlet上下文和参数Map构造Dispatcher ,Dispatcher初始化,加载struts2的相关配置文件)------>初始化prepare和excute