项目中配置struts2在web.xml
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
FilterDispatcher是struts2的核心控制器,每个请求都会进入FilterDispatcher对象的doFilter()方法。然后再struts.xml文件中根据action的name属性进行匹配,找到要执行的action类和方法,执行完方法返回结果。
1、首先分析FilterDispatcher加载struts的各种配置文件。
首先看看init()方法:
public void init(FilterConfig filterConfig) throws ServletException {
try {
this.filterConfig = filterConfig;
initLogging();
dispatcher = createDispatcher(filterConfig);
dispatcher.init();
dispatcher.getContainer().inject(this);
staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig));
} finally {
ActionContext.setContext(null);
}
}
注释:(1)iniggtLoing()初始化log日志
(2)createDispatcher(filterConfig)创建dispatcher,并且通过init()初始化相应的信息
2、createDispatcher(filterConfig)方法代码:
protected Dispatcher createDispatcher(FilterConfig filterConfig) {
Map<String, String> params = new HashMap<String, String>();
for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {
String name = (String) e.nextElement();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
}
return createDispatcher(filterConfig.getServletContext(), params);
}
注释:主要是把web.xml中init-param的标签数据保存到类型map的params中,然后继续调用createDispatcher(filterConfig.getServletContext(), params)创建dispatcher
3、createDispatcher(filterConfig.getServletContext(), params)的源码:
protected Dispatcher createDispatcher(ServletContext ctx, Map<String, String> params) {
return new Dispatcher(ctx, params);
}
注释:很简单,就是new Dispatcher对象。Dispather被称之为struts2的核心分发器,主要是基于在整个struts2框架中的特殊地位。
4、Dispatcher的构造函数:
public Dispatcher(ServletContext servletContext, Map<String, String> initParams) {
this.servletContext = servletContext;
this.initParams = initParams;
}
5、创建好d
ispatcher对象,然后回到
步骤1中org.apache.struts2.dispatcher.FilterDispatcher中init()方法,然后会调用dispatcher.init(),
init()方法是用来Load用户配置文件,资源文件以及默认的配置文件.
public void init() {
if (configurationManager == null) {
configurationManager = createConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);////设置ConfigurationManager的defaultFrameworkBeanName. //这里DEFAULT_BEAN_NAME为struts,这是xwork框架的内容,Framework可以是xwork,struts,webwork等 }
try {
init_DefaultProperties(); // [1]//读取properties信息,默认的default.properties init_TraditionalXmlConfigurations(); // [2]读取xml配置文件
init_LegacyStrutsProperties(); // [3]读取用户自定义的struts.properties
init_CustomConfigurationProviders(); // [5]自定义的configProviders
init_FilterInitParameters() ; // [6]载入FilterDispatcher传进来的initParams
init_AliasStandardObjects() ; // [7]将配置文件中的bean与具体的类映射 //构建一个用于依赖注射的Container对象, 在这里面会循环调用上面七个ConfigurationProvider的register方法,其中的重点就是DefaultConfiguration的#reload()方法
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);
}
}
注释:(1)通过createConfigurationManager创建配置控制器,
createConfigurationManager方法就是简单new ConfigurationManager(name)对象。
(2)init_DefaultProperties() 读取properties信息,默认的default.properties,详细分析请看步骤5.1
(3)init_TraditionalXmlConfigurations读取xml配置文件,struts-default.xml,struts-plugin.xml,struts.xml,请看步骤5.2
(4)init_LegacyStrutsProperties()读取用户自定义struts.properties
(5)init_CustomConfigurationProviders()初始化自定义的配置加载器,请看步骤5.3
(6)init_FilterInitParameters()初始化由wen.xml穿件来的运行参数 ,请看步骤5.4
(7)init_AliasStandardObjects()将配置文件中的bean与具体的类映射 ,初始化默认容器内置对象,后面会详细的解释。
到这里初始化各种形式的配置加载方法,这里只是定义了配置和加载的方法,并没有真正执行加载配置的逻辑
下面这几步初始化容器,这里包含两个不同的过程:(1)对所有定义的配置加载方式的逻辑执行,将它们初始化到configuration中(2)初始化struts2中的对象管理器
Container container = init_PreloadConfiguration();
container.inject(this);对container进行依赖注入,所有在struts2中定义的对象的生命周期在此操作后都被纳入容器管理
init_CheckConfigurationReloading(container);
init_CheckWebLogicWorkaround(container);
额外初始化,检查是否支持reloading加载和对weblogic服务器的特殊处理
5.1init_DefaultProperties() 代码:
private void init_DefaultProperties() {
configurationManager.addContainerProvider(new DefaultPropertiesProvider());
}
5.1.1DefaultPropertiesProvider().java代码:
public class DefaultPropertiesProvider extends LegacyPropertiesConfigurationProvider {
public void destroy() {
}
public void init(Configuration configuration) throws ConfigurationException {
}
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);
}
}
注释:初始化struts2默认的properties文件,该文件是org/apache/struts2/目录下的default.properties文件
5.2init_TraditionalXmlConfigurations()加载xml配置
private static final String DEFAULT_CONFIGURATION_PATHS = "struts-default.xml,struts-plugin.xml,struts.xml";
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");
}
}
}
protected XmlConfigurationProvider createStrutsXmlConfigurationProvider(String filename, boolean errorIfMissing, ServletContext ctx) {
return new StrutsXmlConfigurationProvider(filename, errorIfMissing, ctx);
}
5.3init_CustomConfigurationProviders()--初始化用户自定义的配置加载器,代码:
private void init_CustomConfigurationProviders() {
String configProvs = initParams.get("configProviders");
if (configProvs != null) {
String[] classes = configProvs.split("\\s*[,]\\s*");
for (String cname : classes) {
try {
Class cls = ClassLoaderUtils.loadClass(cname, this.getClass());
ConfigurationProvider prov = (ConfigurationProvider)cls.newInstance();
configurationManager.addContainerProvider(prov);
} catch (InstantiationException e) {
throw new ConfigurationException("Unable to instantiate provider: "+cname, e);
} catch (IllegalAccessException e) {
throw new ConfigurationException("Unable to access provider: "+cname, e);
} catch (ClassNotFoundException e) {
throw new ConfigurationException("Unable to locate provider class: "+cname, e);
}
}
}
}
5.4init_FilterInitParameters()--初始化由web.xml传入的运行参数,代码:
private void init_FilterInitParameters() {
configurationManager.addContainerProvider(new ConfigurationProvider() {
public void destroy() {
}
public void init(Configuration configuration) throws ConfigurationException {
}
public void loadPackages() throws ConfigurationException {
}
public boolean needsReload() {
return false;
}
public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
props.putAll(initParams);
}
});
}