Struts2刚开始加载的时候是通过在web.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,在WEB容器启动的时候会调用init方法
public void init(FilterConfig filterConfig) throws ServletException {
InitOperations init = new InitOperations();
Dispatcher dispatcher = null;
try {
FilterHostConfig config = new FilterHostConfig(filterConfig);
init.initLogging(config);
dispatcher = init.initDispatcher(config);
init.initStaticContentLoader(config, dispatcher);
prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);
postInit(dispatcher, filterConfig);
} finally {
if (dispatcher != null) {
dispatcher.cleanUpAfterInit();
}
init.cleanup();
}
}
变量1:init(InitOperations),该类负责各种配置文件和其他类的初始化工作
变量2:filterConfig(FilterConfig):这个就是web.xml中配置的过滤器信息
变量3:config(FilterHostConfig):构造函数是接受FilterConfig,有两个主要的方法
大致是获取配置在web.xml中初始化的参数和获得ServletContext(不确定)
public Iterator<String> getInitParameterNames() {
return MakeIterator.convert(config.getInitParameterNames());
}
public ServletContext getServletContext() {
return config.getServletContext();
}
init.initLogging(config); 这个是配置日志信息
dispatcher = init.initDispatcher(config);这个是根据config产生调度器dispatcher
打开里面的代码
public Dispatcher initDispatcher( HostConfig filterConfig ) {
//创建dispatcher
Dispatcher dispatcher = createDispatcher(filterConfig);
//加载各种默认配置文件
dispatcher.init();
return dispatcher;
}
其中创建createDispatcher的代码部分
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);
}
return new Dispatcher(filterConfig.getServletContext(), params);
}
下面重点来了 dispatcher.init(); 这部分就是dispatcher加载struts2的各种默认配置文件
try {
init_FileManager();
init_DefaultProperties(); // [1]
init_TraditionalXmlConfigurations(); // [2]
init_LegacyStrutsProperties(); // [3]
init_CustomConfigurationProviders(); // [5]
init_FilterInitParameters() ; // [6]
init_AliasStandardObjects() ; // [7]
Container container = init_PreloadConfiguration();
container.inject(this);
init_CheckWebLogicWorkaround(container);
if (!dispatcherListeners.isEmpty()) {
for (DispatcherListener l : dispatcherListeners) {
l.dispatcherInitialized(this);
}
}
}
- [1]、源码部分:
private void init_DefaultProperties() {
configurationManager.addContainerProvider(new DefaultPropertiesProvider());
}
configurationManager管理器 添加一个ContainerProvider,其中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);
}
打开源码后发现原来是加载default.properties这个配置文件
- [2]、源码
private void init_TraditionalXmlConfigurations() {
String configPaths = initParams.get("config");
if (configPaths == null) {
configPaths = DEFAULT_CONFIGURATION_PATHS;
}
String[] files = configPaths.split("\\s*[,]\\s*");
for (String file : files) {
if (file.endsWith(".xml")) {
if ("xwork.xml".equals(file)) {
configurationManager.addContainerProvider(createXmlConfigurationProvider(file, false));
} else {
configurationManager.addContainerProvider(createStrutsXmlConfigurationProvider(file, false, servletContext));
}
} else {
throw new IllegalArgumentException("Invalid configuration file name");
}
}
}
其中configPaths是:struts-default.xml,struts-plugin.xml,struts.xml,这也非常明白了,原来是加载这三个配置文件。
所以和很清楚的知道struts加载配置文件的顺序default.properties、struts-default.xml,struts-plugin.xml,struts.xml
- [3]部分源码:
String loc = context.getContainer().getInstance(String.class, StrutsConstants.STRUTS_LOCALE);
if (loc != null) {
StringTokenizer localeTokens = new StringTokenizer(loc, "_");
String lang = null;
String country = null;
if (localeTokens.hasMoreTokens()) {
lang = localeTokens.nextToken();
}
if (localeTokens.hasMoreTokens()) {
country = localeTokens.nextToken();
}
locale = new Locale(lang, country);
}
这个是加载struts.locale的也就是 国际化的文件
init_CustomConfigurationProviders();
// [5] 这个应该是加载用户自动定义的ConfigurationProviders(不太清楚)
init_FilterInitParameters() ; // [6]
public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
props.putAll(initParams);
}
主要就是把initParams放到props中,props内容是:{struts.velocity.contexts=, struts.multipart.parser=jakarta, struts.el.throwExceptionOnFailure=false, struts.serve.static.browserCache=true, struts.enable.DynamicMethodInvocation=true, struts.multipart.saveDir=, struts.serve.static=true……}这些
这部分我也不太懂
- init_AliasStandardObjects() ; // [7]
这部分大概就是进一步初始化props这个属性,源码我就不贴了