首先是容器加载web.xml
struts注册如下:
<servlet> <servlet-name>action</servlet-name> <servlet-class> org.apache.struts.action.ActionServlet </servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
容器启动的时候加载一个名为ActionServlet的Servlet,在内存创建一个唯一的ActionServlet instence。
部分源码:
public class ActionServlet extends HttpServlet {
protected String config = "/WEB-INF/struts-config.xml";
......
public void init() throws ServletException {
final String configPrefix = "config/";
final int configPrefixLength = configPrefix.length() - 1;
try {
initInternal();
initOther();
initServlet();
initChain();
getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
initModuleConfigFactory();
// Initialize modules as needed
ModuleConfig moduleConfig = initModuleConfig("", config);
initModuleMessageResources(moduleConfig);
initModulePlugIns(moduleConfig);
initModuleFormBeans(moduleConfig);
initModuleForwards(moduleConfig);
initModuleExceptionConfigs(moduleConfig);
initModuleActions(moduleConfig);
moduleConfig.freeze();
Enumeration names = getServletConfig().getInitParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
if (!name.startsWith(configPrefix)) {
continue;
}
String prefix = name.substring(configPrefixLength);
moduleConfig =
initModuleConfig(prefix,
getServletConfig().getInitParameter(name));
initModuleMessageResources(moduleConfig);
initModulePlugIns(moduleConfig);
initModuleFormBeans(moduleConfig);
initModuleForwards(moduleConfig);
initModuleExceptionConfigs(moduleConfig);
initModuleActions(moduleConfig);
moduleConfig.freeze();
}
this.initModulePrefixes(this.getServletContext());
this.destroyConfigDigester();
} ....
protected ModuleConfig initModuleConfig(String prefix, String paths)
throws ServletException {
if (log.isDebugEnabled()) {
log.debug("Initializing module path '" + prefix
+ "' configuration from '" + paths + "'");
}
// Parse the configuration for this module
ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory();
ModuleConfig config = factoryObject.createModuleConfig(prefix);
// Configure the Digester instance we will use
Digester digester = initConfigDigester();
List urls = splitAndResolvePaths(paths);
URL url;
for (Iterator i = urls.iterator(); i.hasNext();) {
url = (URL) i.next();
digester.push(config);
this.parseModuleConfigFile(digester, url);
}
getServletContext().setAttribute(Globals.MODULE_KEY
+ config.getPrefix(), config);
return config;
}
能够看出ModultConfig的一个实例正是由ModultConfigFactory所创建也是Struts配置文件的内存表示,因为配置文件正是有ModultConfig以实例的形式给ActionConfig,FormbeanConfig,ForwardConfig这些类 的对象了,由他们来读取。
ActionServlet处理http请求,在process方法中其实是创建了一个接收了ModultConfig的RequestProcessor实例,由其中的process***方法来处理所有的请求。