ActionServlet.init()
public void init() throws ServletException {
final String configPrefix = "config/";
final int configPrefixLength = configPrefix.length() - 1;
// Wraps the entire initialization in a try/catch to better handle
// unexpected exceptions and errors to provide better feedback
// to the developer
try {
initInternal();
initOther();
initServlet();
initChain();
getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
initModuleConfigFactory();
//读取struts-config.xml,生成config对象,放入到moduleConfig中
// Initialize modules as needed
ModuleConfig moduleConfig = initModuleConfig("", config);
//根据MessageResourcesConfigs生成MessageResources
initModuleMessageResources(moduleConfig);
//根据PlugInConfigs生产plugIns
initModulePlugIns(moduleConfig);
//初始化formbeanconfig,包括动态bean的配置
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();
} catch (UnavailableException ex) {
throw ex;
} catch (Throwable t) {
// The follow error message is not retrieved from internal message
// resources as they may not have been able to have been
// initialized
log.error("Unable to initialize Struts ActionServlet due to an "
+ "unexpected exception or error thrown, so marking the "
+ "servlet as unavailable. Most likely, this is due to an "
+ "incorrect or missing library dependency.", t);
throw new UnavailableException(t.getMessage());
}
}
1、initModuleMessageResources
protected void initModuleMessageResources(ModuleConfig config)
throws ServletException {
//struts-config.xml中配置的MessageResourcesConfig
MessageResourcesConfig[] mrcs = config.findMessageResourcesConfigs();
for (int i = 0; i < mrcs.length; i++) {
if ((mrcs[i].getFactory() == null)
|| (mrcs[i].getParameter() == null)) {
continue;
}
if (log.isDebugEnabled()) {
log.debug("Initializing module path '" + config.getPrefix()
+ "' message resources from '" + mrcs[i].getParameter()
+ "'");
}
<span style="white-space:pre"> </span>//这个默认是org.apache.struts.util.PropertyMessageResourcesFactory
String factory = mrcs[i].getFactory();
MessageResourcesFactory.setFactoryClass(factory);
<span style="white-space:pre"> </span>//默认是org.apache.struts.util.PropertyMessageResourcesFactory的实例
MessageResourcesFactory factoryObject =
MessageResourcesFactory.createFactory();
factoryObject.setConfig(mrcs[i]);
<span style="white-space:pre"> </span>//parameter实际上是资源文件路径。MessageResources 是在第一次使用时加载的。
MessageResources resources =
factoryObject.createResources(mrcs[i].getParameter());
resources.setReturnNull(mrcs[i].getNull());
resources.setEscape(mrcs[i].isEscape());
getServletContext().setAttribute(mrcs[i].getKey()
+ config.getPrefix(), resources);
}
}
2、initModulePlugIns
protected void initModulePlugIns(ModuleConfig config)
throws ServletException {
if (log.isDebugEnabled()) {
log.debug("Initializing module path '" + config.getPrefix()
+ "' plug ins");
}
PlugInConfig[] plugInConfigs = config.findPlugInConfigs();
PlugIn[] plugIns = new PlugIn[plugInConfigs.length];
getServletContext().setAttribute(Globals.PLUG_INS_KEY
+ config.getPrefix(), plugIns);
for (int i = 0; i < plugIns.length; i++) {
try {
plugIns[i] =
(PlugIn) RequestUtils.applicationInstance(plugInConfigs[i]
.getClassName());
//这个工具方法是把plugInConfigs[i].getProperties()这个键值对,赋值给plugIns[i]
BeanUtils.populate(plugIns[i], plugInConfigs[i].getProperties());
// Pass the current plugIn config object to the PlugIn.
// The property is set only if the plugin declares it.
// This plugin config object is needed by Tiles
try {
//org.apache.struts.tiles.TilesPlugin初始化专用
//TilesPlugin是tiles模板专用
PropertyUtils.setProperty(plugIns[i],
"currentPlugInConfigObject", plugInConfigs[i]);
} catch (Exception e) {
;
// FIXME Whenever we fail silently, we must document a valid
// reason for doing so. Why should we fail silently if a
// property can't be set on the plugin?
/**
* Between version 1.138-1.140 cedric made these changes.
* The exceptions are caught to deal with containers
* applying strict security. This was in response to bug
* #15736
*
* Recommend that we make the currentPlugInConfigObject part
* of the PlugIn Interface if we can, Rob
*/
}
plugIns[i].init(this, config);
} catch (ServletException e) {
throw e;
} catch (Exception e) {
String errMsg =
internal.getMessage("plugIn.init",
plugInConfigs[i].getClassName());
log(errMsg, e);
throw new UnavailableException(errMsg);
}
}
}
3、initModuleFormBeans
protected void initModuleFormBeans(ModuleConfig config)
throws ServletException {
if (log.isDebugEnabled()) {
log.debug("Initializing module path '" + config.getPrefix()
+ "' form beans");
}
// Process form bean extensions.
FormBeanConfig[] formBeans = config.findFormBeanConfigs();
for (int i = 0; i < formBeans.length; i++) {
FormBeanConfig beanConfig = formBeans[i];
//处理formbean的继承关系,会把父类属性copy到formbeanconfig
//大致研究了一下,在配置formbean时,可以设置extends,值是formbean的name。不过dtd里面限制了这个属性(extends),可能是不推荐使用吧
processFormBeanExtension(beanConfig, config);
}
for (int i = 0; i < formBeans.length; i++) {
FormBeanConfig formBean = formBeans[i];
// Verify that required fields are all present for the form config
if (formBean.getType() == null) {
handleValueRequiredException("type", formBean.getName(),
"form bean");
}
// ... and the property configs
FormPropertyConfig[] fpcs = formBean.findFormPropertyConfigs();
for (int j = 0; j < fpcs.length; j++) {
FormPropertyConfig property = fpcs[j];
if (property.getType() == null) {
handleValueRequiredException("type", property.getName(),
"form property");
}
}
// Force creation and registration of DynaActionFormClass instances
// for all dynamic form beans
if (formBean.getDynamic()) {
//动态bean配置,初始化dynaActionFormClass = new DynaActionFormClass(this);(this是指formBean)
formBean.getDynaActionFormClass();
}
}
}