您的位置:首页 > 编程语言 > Java开发

struts2源码分析(三)(初始化)(下)

2013-09-29 11:11 537 查看
12)ActionContext oldContext = ActionContext.getContext();

  获取ActionContext的实例。ActionContext的具体方法如下所示:

/**
* 返回特定于当前线程的ActionContext
* @return ActionContext 当前线程的ActionContext
*/
public static ActionContext getContext() {
return (ActionContext) actionContext.get();
}    

 13)setContext(bootstrap);

  调用DefaultConfiguration的setContext(Container cont)方法,其中bootstrap是一个ContainerImpl类的实例,该方法具体内容如下:

/**
* 判断当前ActoinContext的getContext是否存在,如果不存在则创建一个并返回
* @param cont
* @return
*/
protected ActionContext setContext(Container cont) {
//获取当前ActionContext
ActionContext context = ActionContext.getContext();
//判断当前ActionContext是否为空
if (context == null) {
//若为空的话,则新建一个放入ActionContext中(ValueStack未分析)
ValueStack vs = cont.getInstance(ValueStackFactory.class).createValueStack();//从ContainerBuilder中获取一个创建ValueStack的工厂类,并创建一个ValueStack实例
context = new ActionContext(vs.getContext());//创建一个新的ActionContext对象
ActionContext.setContext(context);//添加到ActionContext中
}
return context;//返回当前的ActionContext
}  

  14)container = builder.create(false);

  调用的是ContainerBuilder中的create方法创建一个Container对象,该方法在上面已经对其进行过介绍。

  15)setContext(container);

  把container添加到ActionContext中该方法与13)一样

  16)objectFactory = container.getInstance(ObjectFactory.class);//获取一个objectFactory实例

  17)container.inject(containerProvider);//注入到容器中

  18)((PackageProvider)containerProvider).loadPackages();//调用loadPackages方法

  1:DefaultPropertiesProvider(default.properties)

  该类中为覆盖父类中的loadPackages()方法,此时调用父类中的loadPackages()方法如下

/**
* 加载包,但是在该类里面不执行
*/
public void loadPackages() throws ConfigurationException {
} 

  2:StrutsXmlConfigurationProvider(struts-default.xml)

  该类中的loadPackages()方法如下:

/* (non-Javadoc)
* @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#init(com.opensymphony.xwork2.config.Configuration)
*/
@Override
public void loadPackages() {
ActionContext ctx = ActionContext.getContext();
ctx.put(reloadKey, Boolean.TRUE);//向ActionContext中添加一个一个Map
super.loadPackages();//调用父类的loadPackages()方法
} 

 父类XmlConfigurationProvider中的loadPackages()方法如下:

/**
* 对*.xml中的package进行解析
*/
public void loadPackages() throws ConfigurationException {
List<Element> reloads = new ArrayList<Element>();
//对documents进行遍历
for (Document doc : documents) {
Element rootElement = doc.getDocumentElement();//获取根元素
NodeList children = rootElement.getChildNodes();//获取所有子节点
int childSize = children.getLength();//获取子节点的长度

/**
* 对子节点进行遍历
*/
for (int i = 0; i < childSize; i++) {
Node childNode = children.item(i);//获取第I个子节点

if (childNode instanceof Element) {
Element child = (Element) childNode;//把节点转换成元素

final String nodeName = child.getNodeName();//获取元素的name

//如果该元素名为package
if ("package".equals(nodeName)) {
①PackageConfig cfg = addPackage(child);//解析该节点,并把解析之后的信息放入DefulatConfiguration中的packageContexts中
if (cfg.isNeedsRefresh()) {
②reloads.add(child);
}
}
}
}
③loadExtraConfiguration(doc);
}

if (reloads.size() > 0) {
④reloadRequiredPackages(reloads);
}

for (Document doc : documents) {
⑤loadExtraConfiguration(doc);
}
//清空documents
documents.clear();
configuration = null;//设置configuration为空
}

 ①PackageConfig cfg = addPackage(child);//解析该节点,并把解析之后的信息放入DefulatConfiguration中的packageContexts中

 在这里先看了解一些重要的类

 ResultConfig(com.opensymphony.xwork2.config.entities)类

/**
* 结果的配置,在xml的配置文件中像定义一个result标签一样
*/
public class ResultConfig extends Located implements Serializable {

protected Map<String,String> params;//参数
protected String className;//结果名
protected String name;//结果名称

/**
* 根据给定的name和className实例化一个ResultConfig对象
* @param name 结果名称
* @param className 结果名
*/
protected ResultConfig(String name, String className) {
this.name = name;
this.className = className;
params = new LinkedHashMap<String, String>();
}

/**
* 根据给定的一个ResultConfig对象复制一个新的对象
* @param orig
*/
protected ResultConfig(ResultConfig orig) {
this.params = orig.params;
this.name = orig.name;
this.className = orig.className;
}

/**
* 获取className
* @return
*/
public String getClassName() {
return className;
}

/**
* 获取name
* @return
*/
public String getName() {
return name;
}

/**
* 获取param
* @return
*/
public Map<String,String> getParams() {
return params;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}

if (!(o instanceof ResultConfig)) {
return false;
}

final ResultConfig resultConfig = (ResultConfig) o;

if ((className != null) ? (!className.equals(resultConfig.className)) : (resultConfig.className != null)) {
return false;
}

if ((name != null) ? (!name.equals(resultConfig.name)) : (resultConfig.name != null)) {
return false;
}

if ((params != null) ? (!params.equals(resultConfig.params)) : (resultConfig.params != null)) {
return false;
}

return true;
}

@Override
public int hashCode() {
int result;
result = ((name != null) ? name.hashCode() : 0);
result = (29 * result) + ((className != null) ? className.hashCode() : 0);
result = (29 * result) + ((params != null) ? params.hashCode() : 0);

return result;
}

/**
* 这个类的builder方法。唯一创建该类的实例的方法。目的是为了维持执行对象的不变性。
* 该方式是通过结构化的方式来至此chain方式。设置完需要的参数之后,可以调用build方法创建一个实例
*/
public static final class Builder {
protected ResultConfig target;//创建一个对象

/**
* 实例化该对象
* @param name
* @param className
*/
public Builder(String name, String className) {
target = new ResultConfig(name, className);
}

/**
* 复制一个该对象
* @param orig
*/
public Builder(ResultConfig orig) {
target = new ResultConfig(orig);
}

/**
* 设定该对象的名称
* @param name
* @return
*/
public Builder name(String name) {
target.name = name;
return this;
}

/**
* 设定该对象的结果明
* @param name
* @return
*/
public Builder className(String name) {
target.className = name;
return this;
}

/**
* 添加一个参数
* @param name
* @param value
* @return
*/
public Builder addParam(String name, String value) {
target.params.put(name, value);
return this;
}

/**
* 添加一个map类型的参数集合
* @param params
* @return
*/
public Builder addParams(Map<String,String> params) {
target.params.putAll(params);
return this;
}

/**
* 设置该对象的location
* @param loc
* @return
*/
public Builder location(Location loc) {
target.location = loc;
return this;
}

/**
* 创建该对象
* @return
*/
public ResultConfig build() {
embalmTarget();
ResultConfig result = target;
target = new ResultConfig(target);
return result;
}

protected void embalmTarget() {
target.params = Collections.unmodifiableMap(target.params);
}
}
}

  InterceptorMapping(com.opensymphony.xwork2.config.entities)

/**
* 拦截器Mapping
*/
public class InterceptorMapping implements Serializable {

private String name;//拦截器名
private Interceptor interceptor;//拦截器实现类

public InterceptorMapping(String name, Interceptor interceptor) {
this.name = name;
this.interceptor = interceptor;
}

public String getName() {
return name;
}

public Interceptor getInterceptor() {
return interceptor;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

final InterceptorMapping that = (InterceptorMapping) o;

if (name != null ? !name.equals(that.name) : that.name != null) return false;

return true;
}

@Override
public int hashCode() {
int result;
result = (name != null ? name.hashCode() : 0);
return result;
}
}

 ExceptionMappingConfig(com.opensymphony.xwork2.config.entities)

/**
* 异常映射的配置
*/
public class ExceptionMappingConfig extends Located implements Serializable {

protected String name;//名称
protected String exceptionClassName;//异常类名称
protected String result;//结果
protected Map<String,String> params;//参数

/**
* 初始化一个ExceptionMappingConfig对象
* @param name 名称
* @param exceptionClassName 异常类名称
* @param result 结果
*/
protected ExceptionMappingConfig(String name, String exceptionClassName, String result) {
this.name = name;
this.exceptionClassName = exceptionClassName;
this.result = result;
this.params = new LinkedHashMap<String,String>();
}

/**
* 根据现有的一个ExceptionMappingConfig实例化一个新的ExceptionMappingConfig对象
* @param target
*/
protected ExceptionMappingConfig(ExceptionMappingConfig target) {
this.name = target.name;
this.exceptionClassName = target.exceptionClassName;
this.result = target.result;
this.params = new LinkedHashMap<String,String>(target.params);
}

/**
* 获取名称
* @return
*/
public String getName() {
return name;
}

/**
* 获取异常类名称
* @return
*/
public String getExceptionClassName() {
return exceptionClassName;
}

/**
* 获取结果
* @return
*/
public String getResult() {
return result;
}

/**
* 获取参数集合
* @return
*/
public Map<String,String> getParams() {
return params;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}

if (!(o instanceof ExceptionMappingConfig)) {
return false;
}

final ExceptionMappingConfig exceptionMappingConfig = (ExceptionMappingConfig) o;

if ((name != null) ? (!name.equals(exceptionMappingConfig.name)) : (exceptionMappingConfig.name != null)) {
return false;
}

if ((exceptionClassName != null) ? (!exceptionClassName.equals(exceptionMappingConfig.exceptionClassName)) : (exceptionMappingConfig.exceptionClassName != null))
{
return false;
}

if ((result != null) ? (!result.equals(exceptionMappingConfig.result)) : (exceptionMappingConfig.result != null))
{
return false;
}

if ((params != null) ? (!params.equals(exceptionMappingConfig.params)) : (exceptionMappingConfig.params != null))
{
return false;
}

return true;
}

@Override
public int hashCode() {
int hashCode;
hashCode = ((name != null) ? name.hashCode() : 0);
hashCode = (29 * hashCode) + ((exceptionClassName != null) ? exceptionClassName.hashCode() : 0);
hashCode = (29 * hashCode) + ((result != null) ? result.hashCode() : 0);
hashCode = (29 * hashCode) + ((params != null) ? params.hashCode() : 0);

return hashCode;
}

/**
* 这个类的builder方法。唯一创建该类的实例的方法。目的是为了维持执行对象的不变性。
* 该方式是通过结构化的方式来至此chain方式。设置完需要的参数之后,可以调用build方法创建一个实例
*/
public static class Builder{

/**
* 声明一个ExceptionMappingConfig实例
*/
protected ExceptionMappingConfig target;

/**
* 根据现有的实例克隆一个target对象
* @param toClone
*/
public Builder(ExceptionMappingConfig toClone) {
target = new ExceptionMappingConfig(toClone);
}

/**
* 利用构造方法创建一个target对象
* @param name
* @param exceptionClassName
* @param result
*/
public Builder(String name, String exceptionClassName, String result) {
target = new ExceptionMappingConfig(name, exceptionClassName, result);
}

/**
* 设置名称
* @param name
* @return
*/
public Builder name(String name) {
target.name = name;
return this;
}

/**
* 设置异常类名称
* @param name
* @return
*/
public Builder exceptionClassName(String name) {
target.exceptionClassName = name;
return this;
}

/**
* 设置结果
* @param result
* @return
*/
public Builder result(String result) {
target.result = result;
return this;
}

/**
* 添加参数
* @param name
* @param value
* @return
*/
public Builder addParam(String name, String value) {
target.params.put(name, value);
return this;
}

/**
* 添加一个map类型
* @param params
* @return
*/
public Builder addParams(Map<String,String> params) {
target.params.putAll(params);
return this;
}

public Builder location(Location loc) {
target.location = loc;
return this;
}

/**
* 创建该ExceptionMappingConfig对象
* @return
*/
public ExceptionMappingConfig build() {
embalmTarget();
ExceptionMappingConfig result = target;
target = new ExceptionMappingConfig(target);
return result;
}

protected void embalmTarget() {
target.params = Collections.unmodifiableMap(target.params);
}
}

} 

 ResultTypeConfig(com.opensymphony.xwork2.config.entities)

/**
* 返回结果类型的配置,在xml的配置文件中这相当于定义一个result-type类型
*/
public class ResultTypeConfig extends Located implements Serializable {

protected String className;//类名
protected String name;//类型名称
protected String defaultResultParam;//默认的结果参数
protected Map<String,String> params;//参数集

/**
* 默认构造方法,在这里初始化该类的一些参数
* @param name
* @param className
*/
protected ResultTypeConfig(String name, String className) {
this.name = name;
this.className = className;
params = new LinkedHashMap<String,String>();
}

/**
* 根据现有的一个该类的实例克隆一个新的对象
* @param orig
*/
protected ResultTypeConfig(ResultTypeConfig orig) {
this.name = orig.name;
this.className = orig.className;
this.defaultResultParam = orig.defaultResultParam;
this.params = orig.params;
}

/**
* 设置默认的结果参数
* @param defaultResultParam
*/
public void setDefaultResultParam(String defaultResultParam) {
this.defaultResultParam = defaultResultParam;
}

/**
* 获取默认的结果参数
* @return
*/
public String getDefaultResultParam() {
return this.defaultResultParam;
}

/**
* @deprecated Since 2.1, use {@link #getClassName()} instead
*/
@Deprecated public String getClazz() {
return className;
}

public String getClassName() {
return className;
}

public String getName() {
return name;
}

public Map<String,String> getParams() {
return this.params;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

final ResultTypeConfig that = (ResultTypeConfig) o;

if (className != null ? !className.equals(that.className) : that.className != null) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (params != null ? !params.equals(that.params) : that.params != null) return false;

return true;
}

@Override
public int hashCode() {
int result;
result = (className != null ? className.hashCode() : 0);
result = 29 * result + (name != null ? name.hashCode() : 0);
result = 29 * result + (params != null ? params.hashCode() : 0);
return result;
}

/**
* 这个类的builder方法。唯一创建该类的实例的方法。目的是为了维持执行对象的不变性。
* 该方式是通过结构化的方式来至此chain方式。设置完需要的参数之后,可以调用build方法创建一个实例
* 一下内部类的方法,通过名称即可了解该方法的具体作用
*/
public static final class Builder {
protected ResultTypeConfig target;

public Builder(String name, String className) {
target = new ResultTypeConfig(name, className);
}

public Builder(ResultTypeConfig orig) {
target = new ResultTypeConfig(orig);
}

public Builder name(String name) {
target.name = name;
return this;
}

public Builder className(String name) {
target.className = name;
return this;
}

public Builder addParam(String name, String value) {
target.params.put(name, value);
return this;
}

public Builder addParams(Map<String,String> params) {
target.params.putAll(params);
return this;
}

public Builder defaultResultParam(String defaultResultParam) {
target.defaultResultParam = defaultResultParam;
return this;
}

public Builder location(Location loc) {
target.location = loc;
return this;
}

public ResultTypeConfig build() {
embalmTarget();
ResultTypeConfig result = target;
target = new ResultTypeConfig(target);
return result;
}

protected void embalmTarget() {
target.params = Collections.unmodifiableMap(target.params);
}
}
}

 ActionConfig(com.opensymphony.xwork2.config.entities)

/**
* 包括所有需要被配置和一个可执行的action
* <ul>
* <li>方法名 - 这个方法名是将要被执行的action的方法。如果为空,这个Action将被关联到Action Interface并且执行execute()方法</li>
* <li>类 - 这个Action的类名</li>
* <li>参数 - 这些参数将被在action执行之前设置</li>
* <li>结果 - 结果集 {String -> View class}</li>
* <li>结果参数 - 返回结果的参数{String -> Map}</li>
* <li>类型转换 - 用OGNL的类型转换为了使用getting/setting参数时</li>
* </ul>
*/
public class ActionConfig extends Located implements Serializable {

public static final String DEFAULT_METHOD = "execute";//默认执行的方法名
public static final String WILDCARD = "*";//通配符

protected List<InterceptorMapping> interceptors; // 一个InterceptorMapping的列表对象
protected Map<String,String> params;//参数
protected Map<String, ResultConfig> results;//结果集
protected List<ExceptionMappingConfig> exceptionMappings;//异常映射配置
protected String className;//类名
protected String methodName;//方法名
protected String packageName;//包名
protected String name;//名称
protected Set<String> allowedMethods;

/**
* 构造方法
* @param packageName
* @param name
* @param className
*/
protected ActionConfig(String packageName, String name, String className) {
this.packageName = packageName;
this.name = name;
this.className = className;
params = new LinkedHashMap<String, String>();
results = new LinkedHashMap<String, ResultConfig>();
interceptors = new ArrayList<InterceptorMapping>();
exceptionMappings = new ArrayList<ExceptionMappingConfig>();
allowedMethods = new HashSet<String>();
}

/**
* 负责一个ActionConfig对象
* @param orig The ActionConfig to clone
* @Since 2.1
*/
protected ActionConfig(ActionConfig orig) {
this.name = orig.name;
this.className = orig.className;
this.methodName = orig.methodName;
this.packageName = orig.packageName;
this.params = new LinkedHashMap<String,String>(orig.params);
this.interceptors = new ArrayList<InterceptorMapping>(orig.interceptors);
this.results = new LinkedHashMap<String,ResultConfig>(orig.results);
this.exceptionMappings = new ArrayList<ExceptionMappingConfig>(orig.exceptionMappings);
this.allowedMethods = new HashSet<String>(orig.allowedMethods);
}

public String getName() {
return name;
}

public String getClassName() {
return className;
}

public List<ExceptionMappingConfig> getExceptionMappings() {
return exceptionMappings;
}

public List<InterceptorMapping> getInterceptors() {
return interceptors;
}

public Set<String> getAllowedMethods() {
return allowedMethods;
}

/**
* 返回类中方法的名字
*
* @return name of the method to execute
*/
public String getMethodName() {
return methodName;
}

/**
* @return Returns the packageName.
*/
public String getPackageName() {
return packageName;
}

public Map<String, String> getParams() {
return params;
}

public Map<String, ResultConfig> getResults() {
return results;
}

public boolean isAllowedMethod(String method) {
if (allowedMethods.size() == 1 && WILDCARD.equals(allowedMethods.iterator().next())) {
return true;
} else {
return method.equals(methodName != null ? methodName : DEFAULT_METHOD) || allowedMethods.contains(method);
}
}

@Override public boolean equals(Object o) {
if (this == o) {
return true;
}

if (!(o instanceof ActionConfig)) {
return false;
}

final ActionConfig actionConfig = (ActionConfig) o;

if ((className != null) ? (!className.equals(actionConfig.className)) : (actionConfig.className != null)) {
return false;
}

if ((name != null) ? (!name.equals(actionConfig.name)) : (actionConfig.name != null)) {
return false;
}

if ((interceptors != null) ? (!interceptors.equals(actionConfig.interceptors)) : (actionConfig.interceptors != null))
{
return false;
}

if ((methodName != null) ? (!methodName.equals(actionConfig.methodName)) : (actionConfig.methodName != null)) {
return false;
}

if ((params != null) ? (!params.equals(actionConfig.params)) : (actionConfig.params != null)) {
return false;
}

if ((results != null) ? (!results.equals(actionConfig.results)) : (actionConfig.results != null)) {
return false;
}

if ((allowedMethods != null) ? (!allowedMethods.equals(actionConfig.allowedMethods)) : (actionConfig.allowedMethods != null)) {
return false;
}

return true;
}

@Override public int hashCode() {
int result;
result = (interceptors != null ? interceptors.hashCode() : 0);
result = 31 * result + (params != null ? params.hashCode() : 0);
result = 31 * result + (results != null ? results.hashCode() : 0);
result = 31 * result + (exceptionMappings != null ? exceptionMappings.hashCode() : 0);
result = 31 * result + (className != null ? className.hashCode() : 0);
result = 31 * result + (methodName != null ? methodName.hashCode() : 0);
result = 31 * result + (packageName != null ? packageName.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (allowedMethods != null ? allowedMethods.hashCode() : 0);
return result;
}

@Override public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("{ActionConfig ");
sb.append(name).append(" (");
sb.append(className);
if (methodName != null) {
sb.append(".").append(methodName).append("()");
}
sb.append(")");
sb.append(" - ").append(location);
sb.append("}");
return sb.toString();
}

/**
* 这个类的builder方法。唯一创建该类的实例的方法。目的是为了维持执行对象的不变性。
* 该方式是通过结构化的方式来至此chain方式。设置完需要的参数之后,可以调用build方法创建一个实例
*/
public static class Builder implements InterceptorListHolder{

protected ActionConfig target;
private boolean gotMethods;

public Builder(ActionConfig toClone) {
target = new ActionConfig(toClone);
addAllowedMethod(toClone.getAllowedMethods());
}

public Builder(String packageName, String name, String className) {
target = new ActionConfig(packageName, name, className);
}

public Builder packageName(String name) {
target.packageName = name;
return this;
}

public Builder name(String name) {
target.name = name;
return this;
}

public Builder className(String name) {
target.className = name;
return this;
}

public Builder defaultClassName(String name) {
if (StringUtils.isEmpty(target.className)) {
target.className = name;
}
return this;
}

public Builder methodName(String method) {
target.methodName = method;
return this;
}

public Builder addExceptionMapping(ExceptionMappingConfig exceptionMapping) {
target.exceptionMappings.add(exceptionMapping);
return this;
}

public Builder addExceptionMappings(Collection<? extends ExceptionMappingConfig> mappings) {
target.exceptionMappings.addAll(mappings);
return this;
}

public Builder exceptionMappings(Collection<? extends ExceptionMappingConfig> mappings) {
target.exceptionMappings.clear();
target.exceptionMappings.addAll(mappings);
return this;
}

public Builder addInterceptor(InterceptorMapping interceptor) {
target.interceptors.add(interceptor);
return this;
}

public Builder addInterceptors(List<InterceptorMapping> interceptors) {
target.interceptors.addAll(interceptors);
return this;
}

public Builder interceptors(List<InterceptorMapping> interceptors) {
target.interceptors.clear();
target.interceptors.addAll(interceptors);
return this;
}

public Builder addParam(String name, String value) {
target.params.put(name, value);
return this;
}

public Builder addParams(Map<String,String> params) {
target.params.putAll(params);
return this;
}

public Builder addResultConfig(ResultConfig resultConfig) {
target.results.put(resultConfig.getName(), resultConfig);
return this;
}

public Builder addResultConfigs(Collection<ResultConfig> configs) {
for (ResultConfig rc : configs) {
target.results.put(rc.getName(), rc);
}
return this;
}

public Builder addResultConfigs(Map<String,ResultConfig> configs) {
target.results.putAll(configs);
return this;
}

public Builder addAllowedMethod(String methodName) {
target.allowedMethods.add(methodName);
return this;
}

public Builder addAllowedMethod(Collection<String> methods) {
if (methods != null) {
gotMethods = true;
target.allowedMethods.addAll(methods);
}
return this;
}

public Builder location(Location loc) {
target.location = loc;
return this;
}

public ActionConfig build() {
embalmTarget();
ActionConfig result = target;
target = new ActionConfig(target);
return result;
}

protected void embalmTarget() {
if (!gotMethods && target.allowedMethods.isEmpty()) {
target.allowedMethods.add(WILDCARD);
}

target.params = Collections.unmodifiableMap(target.params);
target.results = Collections.unmodifiableMap(target.results);
target.interceptors = Collections.unmodifiableList(target.interceptors);
target.exceptionMappings = Collections.unmodifiableList(target.exceptionMappings);
target.allowedMethods = Collections.unmodifiableSet(target.allowedMethods);
}
}
}

  PackageConfig(com.opensymphony.xwork2.config.entities)

/**
* package的配置,在xml配置文件中,对应package标签
*/
public class PackageConfig extends Located implements Comparable, Serializable, InterceptorLocator {

private static final Logger LOG = LoggerFactory.getLogger(PackageConfig.class);

protected Map<String, ActionConfig> actionConfigs;//定义一个ActionConfig的Map列表(相当于xml配置文件中的action)
protected Map<String, ResultConfig> globalResultConfigs;//定义全局结果映射配置
protected Map<String, Object> interceptorConfigs;//定义拦截器名字和类的映射关系
protected Map<String, ResultTypeConfig> resultTypeConfigs;//返回类型的配置
protected List<ExceptionMappingConfig> globalExceptionMappingConfigs;//全集异常映射配置
protected List<PackageConfig> parents;//父package
protected String defaultInterceptorRef;//默认拦截器
protected String defaultActionRef;//默认Action-ref
protected String defaultResultType;//默认返回结果类型
protected String defaultClassRef;
protected String name;//package名称
protected String namespace = "";//namespace
protected boolean isAbstract = false;
protected boolean needsRefresh;

/**
* 初始化所有参数
* @param name
*/
protected PackageConfig(String name) {
this.name = name;
actionConfigs = new LinkedHashMap<String, ActionConfig>();
globalResultConfigs = new LinkedHashMap<String, ResultConfig>();
interceptorConfigs = new LinkedHashMap<String, Object>();
resultTypeConfigs = new LinkedHashMap<String, ResultTypeConfig>();
globalExceptionMappingConfigs = new ArrayList<ExceptionMappingConfig>();
parents = new ArrayList<PackageConfig>();
}

/**
* 通过现有的PackageConfig初始化所有的参数信息
* @param orig
*/
protected PackageConfig(PackageConfig orig) {
this.defaultInterceptorRef = orig.defaultInterceptorRef;
this.defaultActionRef = orig.defaultActionRef;
this.defaultResultType = orig.defaultResultType;
this.defaultClassRef = orig.defaultClassRef;
this.name = orig.name;
this.namespace = orig.namespace;
this.isAbstract = orig.isAbstract;
this.needsRefresh = orig.needsRefresh;
this.actionConfigs = new LinkedHashMap<String, ActionConfig>(orig.actionConfigs);
this.globalResultConfigs = new LinkedHashMap<String, ResultConfig>(orig.globalResultConfigs);
this.interceptorConfigs = new LinkedHashMap<String, Object>(orig.interceptorConfigs);
this.resultTypeConfigs = new LinkedHashMap<String, ResultTypeConfig>(orig.resultTypeConfigs);
this.globalExceptionMappingConfigs = new ArrayList<ExceptionMappingConfig>(orig.globalExceptionMappingConfigs);
this.parents = new ArrayList<PackageConfig>(orig.parents);
}

/**
* 返回是否是抽象的
* @return
*/
public boolean isAbstract() {
return isAbstract;
}

/**
* 返回actionConfigs
* @return
*/
public Map<String, ActionConfig> getActionConfigs() {
return actionConfigs;
}

/**
* 返回当前package中所有可用的ActionConfigs映射,在父类packages中定义的ActionConfigs将被包含在这个Map里面
* @return 一个以action作为名词的ActionConfig对象的Map
* @see ActionConfig
*/
public Map<String, ActionConfig> getAllActionConfigs() {
Map<String, ActionConfig> retMap = new LinkedHashMap<String, ActionConfig>();

if (!parents.isEmpty()) {
for (PackageConfig parent : parents) {
retMap.putAll(parent.getAllActionConfigs());
}
}

retMap.putAll(getActionConfigs());

return retMap;
}

/**
* returns the Map of all the global ResultConfigs available in the current package.
* Global ResultConfigs defined in ancestor packages will be included in this Map.
*
* @return a Map of Result Objects with the result name as the key
* @see ResultConfig
*/
public Map<String, ResultConfig> getAllGlobalResults() {
Map<String, ResultConfig> retMap = new LinkedHashMap<String, ResultConfig>();

if (!parents.isEmpty()) {
for (PackageConfig parentConfig : parents) {
retMap.putAll(parentConfig.getAllGlobalResults());
}
}

retMap.putAll(getGlobalResultConfigs());

return retMap;
}

/**
* returns the Map of all InterceptorConfigs and InterceptorStackConfigs available in the current package.
* InterceptorConfigs defined in ancestor packages will be included in this Map.
*
* @return a Map of InterceptorConfig and InterceptorStackConfig Objects with the ref-name as the key
* @see InterceptorConfig
* @see InterceptorStackConfig
*/
public Map<String, Object> getAllInterceptorConfigs() {
Map<String, Object> retMap = new LinkedHashMap<String, Object>();

if (!parents.isEmpty()) {
for (PackageConfig parentContext : parents) {
retMap.putAll(parentContext.getAllInterceptorConfigs());
}
}

retMap.putAll(getInterceptorConfigs());

return retMap;
}

/**
* returns the Map of all the ResultTypeConfigs available in the current package.
* ResultTypeConfigs defined in ancestor packages will be included in this Map.
*
* @return a Map of ResultTypeConfig Objects with the result type name as the key
* @see ResultTypeConfig
*/
public Map<String, ResultTypeConfig> getAllResultTypeConfigs() {
Map<String, ResultTypeConfig> retMap = new LinkedHashMap<String, ResultTypeConfig>();

if (!parents.isEmpty()) {
for (PackageConfig parentContext : parents) {
retMap.putAll(parentContext.getAllResultTypeConfigs());
}
}

retMap.putAll(getResultTypeConfigs());

return retMap;
}

/**
* returns the List of all the ExceptionMappingConfigs available in the current package.
* ExceptionMappingConfigs defined in ancestor packages will be included in this list.
*
* @return a List of ExceptionMappingConfigs Objects with the result type name as the key
* @see ExceptionMappingConfig
*/
public List<ExceptionMappingConfig> getAllExceptionMappingConfigs() {
List<ExceptionMappingConfig> allExceptionMappings = new ArrayList<ExceptionMappingConfig>();

if (!parents.isEmpty()) {
for (PackageConfig parentContext : parents) {
allExceptionMappings.addAll(parentContext.getAllExceptionMappingConfigs());
}
}

allExceptionMappings.addAll(getGlobalExceptionMappingConfigs());

return allExceptionMappings;
}

public String getDefaultInterceptorRef() {
return defaultInterceptorRef;
}

public String getDefaultActionRef() {
return defaultActionRef;
}

public String getDefaultClassRef() {
if ((defaultClassRef == null) && !parents.isEmpty()) {
for (PackageConfig parent : parents) {
String parentDefault = parent.getDefaultClassRef();
if (parentDefault != null) {
return parentDefault;
}
}
}
return defaultClassRef;
}

/**
* Returns the default result type for this package.
*/
public String getDefaultResultType() {
return defaultResultType;
}

/**
* gets the default interceptor-ref name. If this is not set on this PackageConfig, it searches the parent
* PackageConfigs in order until it finds one.
*/
public String getFullDefaultInterceptorRef() {
if ((defaultInterceptorRef == null) && !parents.isEmpty()) {
for (PackageConfig parent : parents) {
String parentDefault = parent.getFullDefaultInterceptorRef();

if (parentDefault != null) {
return parentDefault;
}
}
}

return defaultInterceptorRef;
}

/**
* gets the default action-ref name. If this is not set on this PackageConfig, it searches the parent
* PackageConfigs in order until it finds one.
*/
public String getFullDefaultActionRef() {
if ((defaultActionRef == null) && !parents.isEmpty()) {
for (PackageConfig parent : parents) {
String parentDefault = parent.getFullDefaultActionRef();

if (parentDefault != null) {
return parentDefault;
}
}
}
return defaultActionRef;
}

/**
* 返回该package的默认的result type
* 如果该package没有默认的result tyoe,但是它有父package,我们将尝试寻找该package的父package的默认result type
*/
public String getFullDefaultResultType() {
if ((defaultResultType == null) && !parents.isEmpty()) {
for (PackageConfig parent : parents) {
String parentDefault = parent.getFullDefaultResultType();

if (parentDefault != null) {
return parentDefault;
}
}
}

return defaultResultType;
}

/**
* gets the global ResultConfigs local to this package
*
* @return a Map of ResultConfig objects keyed by result name
* @see ResultConfig
*/
public Map<String, ResultConfig> getGlobalResultConfigs() {
return globalResultConfigs;
}

/**
* gets the InterceptorConfigs and InterceptorStackConfigs local to this package
*
* @return a Map of InterceptorConfig and InterceptorStackConfig objects keyed by ref-name
* @see InterceptorConfig
* @see InterceptorStackConfig
*/
public Map<String, Object> getInterceptorConfigs() {
return interceptorConfigs;
}

public String getName() {
return name;
}

public String getNamespace() {
return namespace;
}

public List<PackageConfig> getParents() {
return new ArrayList<PackageConfig>(parents);
}

/**
* gets the ResultTypeConfigs local to this package
*
* @return a Map of ResultTypeConfig objects keyed by result name
* @see ResultTypeConfig
*/
public Map<String, ResultTypeConfig> getResultTypeConfigs() {
return resultTypeConfigs;
}

public boolean isNeedsRefresh() {
return needsRefresh;
}

/**
* gets the ExceptionMappingConfigs local to this package
*
* @return a Map of ExceptionMappingConfig objects keyed by result name
* @see ExceptionMappingConfig
*/
public List<ExceptionMappingConfig> getGlobalExceptionMappingConfigs() {
return globalExceptionMappingConfigs;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}

if (!(o instanceof PackageConfig)) {
return false;
}

final PackageConfig packageConfig = (PackageConfig) o;

if (isAbstract != packageConfig.isAbstract) {
return false;
}

if ((actionConfigs != null) ? (!actionConfigs.equals(packageConfig.actionConfigs)) : (packageConfig.actionConfigs != null)) {
return false;
}

if ((defaultResultType != null) ? (!defaultResultType.equals(packageConfig.defaultResultType)) : (packageConfig.defaultResultType != null)) {
return false;
}

if ((defaultClassRef != null) ? (!defaultClassRef.equals(packageConfig.defaultClassRef)) : (packageConfig.defaultClassRef != null)) {
return false;
}

if ((globalResultConfigs != null) ? (!globalResultConfigs.equals(packageConfig.globalResultConfigs)) : (packageConfig.globalResultConfigs != null)) {
return false;
}

if ((interceptorConfigs != null) ? (!interceptorConfigs.equals(packageConfig.interceptorConfigs)) : (packageConfig.interceptorConfigs != null)) {
return false;
}

if ((name != null) ? (!name.equals(packageConfig.name)) : (packageConfig.name != null)) {
return false;
}

if ((namespace != null) ? (!namespace.equals(packageConfig.namespace)) : (packageConfig.namespace != null)) {
return false;
}

if ((parents != null) ? (!parents.equals(packageConfig.parents)) : (packageConfig.parents != null)) {
return false;
}

if ((resultTypeConfigs != null) ? (!resultTypeConfigs.equals(packageConfig.resultTypeConfigs)) : (packageConfig.resultTypeConfigs != null)) {
return false;
}

if ((globalExceptionMappingConfigs != null) ? (!globalExceptionMappingConfigs.equals(packageConfig.globalExceptionMappingConfigs)) : (packageConfig.globalExceptionMappingConfigs != null)) {
return false;
}

return true;
}

@Override
public int hashCode() {
int result;
result = ((name != null) ? name.hashCode() : 0);
result = (29 * result) + ((parents != null) ? parents.hashCode() : 0);
result = (29 * result) + ((actionConfigs != null) ? actionConfigs.hashCode() : 0);
result = (29 * result) + ((globalResultConfigs != null) ? globalResultConfigs.hashCode() : 0);
result = (29 * result) + ((interceptorConfigs != null) ? interceptorConfigs.hashCode() : 0);
result = (29 * result) + ((resultTypeConfigs != null) ? resultTypeConfigs.hashCode() : 0);
result = (29 * result) + ((globalExceptionMappingConfigs != null) ? globalExceptionMappingConfigs.hashCode() : 0);
result = (29 * result) + ((defaultResultType != null) ? defaultResultType.hashCode() : 0);
result = (29 * result) + ((defaultClassRef != null) ? defaultClassRef.hashCode() : 0);
result = (29 * result) + ((namespace != null) ? namespace.hashCode() : 0);
result = (29 * result) + (isAbstract ? 1 : 0);

return result;
}

@Override
public String toString() {
return "{PackageConfig Name:" + name + " namespace:" + namespace + " parents:" + parents + "}";
}

public int compareTo(Object o) {
PackageConfig other = (PackageConfig) o;
String full = namespace + "!" + name;
String otherFull = other.namespace + "!" + other.name;

// note, this isn't perfect (could come from different parents), but it is "good enough"
return full.compareTo(otherFull);
}

public Object getInterceptorConfig(String name) {
return getAllInterceptorConfigs().get(name);
}

/**
* 这个类的构建类。该实例是唯一创建该对象实例的方法。目的是执行对象的不变性。这个方法将被用来支持链式创建。
* 当设置完了你需要设置的参数之后,通过调用build()方法,就可以常见该对象
*/
public static class Builder implements InterceptorLocator {

//该对象的一个实例
protected PackageConfig target;
private boolean strictDMI;
/**
* 设置package的名称
* @param name
*/
public Builder(String name) {
target = new PackageConfig(name);
}

/**
* 通过复制config创建一个新的PackageConfig对象
* @param config
*/
public Builder(PackageConfig config) {
target = new PackageConfig(config);
}

/**
* 设置target对象的名称
* @param name
* @return
*/
public Builder name(String name) {
target.name = name;
return this;
}

/**
* 设置target对象的isabstract属性
* @param isAbstract
* @return
*/
public Builder isAbstract(boolean isAbstract) {
target.isAbstract = isAbstract;
return this;
}

/**
* 设置对象的defaultInterceptorRef属性
* @param name
* @return
*/
public Builder defaultInterceptorRef(String name) {
target.defaultInterceptorRef = name;
return this;
}

/**
* 设置对象的defaultActionRef属性
* @param name
* @return
*/
public Builder defaultActionRef(String name) {
target.defaultActionRef = name;
return this;
}

/**
* 设置对象的defaultClassRef属性
* @param defaultClassRef
* @return
*/
public Builder defaultClassRef(String defaultClassRef) {
target.defaultClassRef = defaultClassRef;
return this;
}

/**
* 为这个Package设置默认的结果类型
*
* @param defaultResultType
*/
public Builder defaultResultType(String defaultResultType) {
target.defaultResultType = defaultResultType;
return this;
}

/**
* 为当前target设置namespace属性
* @param namespace
* @return
*/
public Builder namespace(String namespace) {
if (namespace == null) {
target.namespace = "";
} else {
target.namespace = namespace;
}
return this;
}

public Builder needsRefresh(boolean needsRefresh) {
target.needsRefresh = needsRefresh;
return this;
}

public Builder addActionConfig(String name, ActionConfig action) {
target.actionConfigs.put(name, action);
return this;
}

public Builder addParents(List<PackageConfig> parents) {
for (PackageConfig config : parents) {
addParent(config);
}
return this;
}

public Builder addGlobalResultConfig(ResultConfig resultConfig) {
target.globalResultConfigs.put(resultConfig.getName(), resultConfig);
return this;
}

public Builder addGlobalResultConfigs(Map<String, ResultConfig> resultConfigs) {
target.globalResultConfigs.putAll(resultConfigs);
return this;
}

public Builder addExceptionMappingConfig(ExceptionMappingConfig exceptionMappingConfig) {
target.globalExceptionMappingConfigs.add(exceptionMappingConfig);
return this;
}

public Builder addGlobalExceptionMappingConfigs(List<ExceptionMappingConfig> exceptionMappingConfigs) {
target.globalExceptionMappingConfigs.addAll(exceptionMappingConfigs);
return this;
}

public Builder addInterceptorConfig(InterceptorConfig config) {
target.interceptorConfigs.put(config.getName(), config);
return this;
}

public Builder addInterceptorStackConfig(InterceptorStackConfig config) {
target.interceptorConfigs.put(config.getName(), config);
return this;
}

public Builder addParent(PackageConfig parent) {
target.parents.add(0, parent);
return this;
}

public Builder addResultTypeConfig(ResultTypeConfig config) {
target.resultTypeConfigs.put(config.getName(), config);
return this;
}

public Builder location(Location loc) {
target.location = loc;
return this;
}

public boolean isNeedsRefresh() {
return target.needsRefresh;
}

public String getDefaultClassRef() {
return target.defaultClassRef;
}

public String getName() {
return target.name;
}

public String getNamespace() {
return target.namespace;
}

/**
* 返回该package的默认的result type
* @return
*/
public String getFullDefaultResultType() {
return target.getFullDefaultResultType();
}

public ResultTypeConfig getResultType(String type) {
return target.getAllResultTypeConfigs().get(type);
}

public Object getInterceptorConfig(String name) {
return target.getAllInterceptorConfigs().get(name);
}

public Builder strictMethodInvocation(boolean strict) {
strictDMI = strict;
return this;
}

public boolean isStrictMethodInvocation() {
return strictDMI;
}

public PackageConfig build() {
embalmTarget();
PackageConfig result = target;
target = new PackageConfig(result);
return result;
}

protected void embalmTarget() {
target.actionConfigs = Collections.unmodifiableMap(target.actionConfigs);
target.globalResultConfigs = Collections.unmodifiableMap(target.globalResultConfigs);
target.interceptorConfigs = Collections.unmodifiableMap(target.interceptorConfigs);
target.resultTypeConfigs = Collections.unmodifiableMap(target.resultTypeConfigs);
target.globalExceptionMappingConfigs = Collections.unmodifiableList(target.globalExceptionMappingConfigs);
target.parents = Collections.unmodifiableList(target.parents);
}

@Override
public String toString() {
return "[BUILDER] " + target.toString();
}
}

}

  这个方法中所需的类基本介绍完了,下面介绍解析过程;在此调用XmlConfigurationProvider类的addPackage(Element packageElement)方法,该方法具体内容如下:

/**
* 创建一个XML元素代表一个packageconfig。
*/
protected PackageConfig addPackage(Element packageElement) throws ConfigurationException {
//创建一个PackageConfig的内部类Builder
PackageConfig.Builder newPackage = buildPackageContext(packageElement);//用该类创建一个package对象

if (newPackage.isNeedsRefresh()) {
return newPackage.build();
}

if (LOG.isDebugEnabled()) {
LOG.debug("Loaded " + newPackage);
}

//为这个package添加result types 和默认的result
addResultTypes(newPackage, packageElement);

//为这个package添加interceptors和interceptor stacks
loadInterceptors(newPackage, packageElement);

//为这个package添加默认的interceptors
loadDefaultInterceptorRef(newPackage, packageElement);

//为这个package添加默认的default-class-ref
loadDefaultClassRef(newPackage, packageElement);

//为package添加全局results
loadGlobalResults(newPackage, packageElement);

//为这个package添加全局的exception
loadGobalExceptionMappings(newPackage, packageElement);

//获取action元素
NodeList actionList = packageElement.getElementsByTagName("action");

//遍历action元素
for (int i = 0; i < actionList.getLength(); i++) {
Element actionElement = (Element) actionList.item(i);//获取第i个action元素
//把该action元素添加到package中
addAction(actionElement, newPackage);
}

// load the default action reference for this package
//为该package加载默认的action
loadDefaultActionRef(newPackage, packageElement);
//实例化一个PackageConfig对象
PackageConfig cfg = newPackage.build();
//把该对象添加到configuration(DefaultConfiguration)的packageContexts中
configuration.addPackageConfig(cfg.getName(), cfg);
//返回该cfg对象
return cfg;
}


在这里对其具体代码进行分析:

//为这个package添加result types 和默认的result

  addResultTypes(newPackage, packageElement);该方法的具体代码如下:

/**
* 为这个package添加result types 和默认的result
* @param packageContext
* @param element
*/
protected void addResultTypes(PackageConfig.Builder packageContext, Element element) {
NodeList resultTypeList = element.getElementsByTagName("result-type");//以getElementsByTagName的形式获取所有的("result-type")
/**
* 对result-type进行遍历
*/
for (int i = 0; i < resultTypeList.getLength(); i++) {
Element resultTypeElement = (Element) resultTypeList.item(i);//获取第I个node对象
String name = resultTypeElement.getAttribute("name");//获取该元素的name属性
String className = resultTypeElement.getAttribute("class");//获取该元素的class属性
String def = resultTypeElement.getAttribute("default");//获取该元素的defaul属性

/**
* 获取该元素的location
*/
Location loc = DomHelper.getLocationObject(resultTypeElement);
//获取指定类名的类
Class clazz = verifyResultType(className, loc);
if (clazz != null) {
String paramName = null;
try {
paramName = (String) clazz.getField("DEFAULT_PARAM").get(null);
}
catch (Throwable t) {
// if we get here, the result type doesn't have a default param defined.
}
/**
* 创建一个ResultTypeConfig对象
*/
ResultTypeConfig.Builder resultType = new ResultTypeConfig.Builder(name, className).defaultResultParam(paramName)
.location(DomHelper.getLocationObject(resultTypeElement));

Map<String, String> params = XmlHelper.getParams(resultTypeElement);

if (!params.isEmpty()) {
resultType.addParams(params);
}
packageContext.addResultTypeConfig(resultType.build());

// 设置默认的结果类型
if ("true".equals(def)) {
packageContext.defaultResultType(name);
}
}
}
}


//为这个package添加interceptors和interceptor stacks

  loadInterceptors(newPackage, packageElement);该方法具体内容如下:

/**
* 为这个package添加interceptors和interceptor stacks
* @param context
* @param element
* @throws ConfigurationException
*/
protected void loadInterceptors(PackageConfig.Builder context, Element element) throws ConfigurationException {
NodeList interceptorList = element.getElementsByTagName("interceptor");//获取所有的interceptor配置
//对获取到的interceptor列表进行遍历
for (int i = 0; i < interceptorList.getLength(); i++) {
Element interceptorElement = (Element) interceptorList.item(i);//获取第i个元素
String name = interceptorElement.getAttribute("name");//获取元素的name
String className = interceptorElement.getAttribute("class");//获取元素的class

Map<String, String> params = XmlHelper.getParams(interceptorElement);
/**
* 创建一个InterceptorConfig对象
*/
InterceptorConfig config = new InterceptorConfig.Builder(name, className)
.addParams(params)
.location(DomHelper.getLocationObject(interceptorElement))
.build();

//把创建的InterceptorConfig对象放入PackageConfig中
context.addInterceptorConfig(config);
}

/**
* 加载InterceptorStack
*/
loadInterceptorStacks(element, context);
}

 在该方法中又调用了设置InterceptorStacks的方法,该方法具体如下:

/**
* 为package加载InterceptorStack
* @param element
* @param context
* @throws ConfigurationException
*/
protected void loadInterceptorStacks(Element element, PackageConfig.Builder context) throws ConfigurationException {
NodeList interceptorStackList = element.getElementsByTagName("interceptor-stack");//获取名字为interceptor-stack的节点

/**
* 对节点进行遍历
*/
for (int i = 0; i < interceptorStackList.getLength(); i++) {
Element interceptorStackElement = (Element) interceptorStackList.item(i);//获取第I个节点

InterceptorStackConfig config = loadInterceptorStack(interceptorStackElement, context);

context.addInterceptorStackConfig(config);
}
}

 在该方法内部调用了loadInterceptorStack方法,该方法具体如下:

/**
* 加载InterceptorStack
*/
protected InterceptorStackConfig loadInterceptorStack(Element element, PackageConfig.Builder context) throws ConfigurationException {
String name = element.getAttribute("name");//得到节点的名字

InterceptorStackConfig.Builder config = new InterceptorStackConfig.Builder(name)
.location(DomHelper.getLocationObject(element));//创建一个InterceptorStackConfig对象
NodeList interceptorRefList = element.getElementsByTagName("interceptor-ref");//查找所有的interceptor-ref的节点

/**
* 对查找到的Node进行遍历
*/
for (int j = 0; j < interceptorRefList.getLength(); j++) {
Element interceptorRefElement = (Element) interceptorRefList.item(j);//获取第J个节点
List<InterceptorMapping> interceptors = lookupInterceptorReference(context, interceptorRefElement);
config.addInterceptors(interceptors);
}

return config.build();
} 

 在该方法内部调用lookupInterceptorReference方法,该方法具体内容如下:

/**
* 从interceptor-ref的名字查找Interceptor类并创建一个实例,并添加到provided List中,或,
* 如果这个ref是一个stack,它将会把这个Interceptor实例从List中添加到一个stack中
* @param interceptorRefElement Element to pull interceptor ref data from
* @param context               The PackageConfig to lookup the interceptor from
* @return A list of Interceptor objects
*/
private List<InterceptorMapping> lookupInterceptorReference(PackageConfig.Builder context, Element interceptorRefElement) throws ConfigurationException {
String refName = interceptorRefElement.getAttribute("name");//获取节点的名称
Map<String, String> refParams = XmlHelper.getParams(interceptorRefElement);

Location loc = LocationUtils.getLocation(interceptorRefElement);
return InterceptorBuilder.constructInterceptorReference(context, refName, refParams, loc, objectFactory);
}

  至此该package的InterceptorStack加载完成

  //为这个package添加默认的interceptors

  loadDefaultInterceptorRef(newPackage, packageElement);

/**
* 加载默认的defaul interceptor
* @param packageContext
* @param element
*/
protected void loadDefaultInterceptorRef(PackageConfig.Builder packageContext, Element element) {
NodeList resultTypeList = element.getElementsByTagName("default-interceptor-ref");//获取package下面的所有的default-interceptor-ref元素
/**
* 若default-interceptor-ref元素多于0个
*/
if (resultTypeList.getLength() > 0) {
//获取第一个default-interceptor节点
Element defaultRefElement = (Element) resultTypeList.item(0);
packageContext.defaultInterceptorRef(defaultRefElement.getAttribute("name"));//把default-interceptor-ref的名字添加到package中
}
}

  //为这个package添加默认的default-class-ref

  loadDefaultClassRef(newPackage, packageElement);

/**
* 加载默认的default-class-ref标签
* @param packageContext
* @param element
*/
protected void loadDefaultClassRef(PackageConfig.Builder packageContext, Element element) {
NodeList defaultClassRefList = element.getElementsByTagName("default-class-ref");//获取所有的default-class-ref节点
//如果在配置文件中节点名的节点大于0
if (defaultClassRefList.getLength() > 0) {
Element defaultClassRefElement = (Element) defaultClassRefList.item(0);//获取第一个节点
packageContext.defaultClassRef(defaultClassRefElement.getAttribute("class"));//放入package的defaultClassRef中
}
}

  //为package添加全局results

  loadGlobalResults(newPackage, packageElement);

/**
* 为package添加全局results
*/
protected void loadGlobalResults(PackageConfig.Builder packageContext, Element packageElement) {
NodeList globalResultList = packageElement.getElementsByTagName("global-results");//查询所有的global-results

//如果在配置文件中节点名的节点大于0
if (globalResultList.getLength() > 0) {
Element globalResultElement = (Element) globalResultList.item(0);//获取该节点的第0个节点
Map<String, ResultConfig> results = buildResults(globalResultElement, packageContext);//创建一个全局result到包的映射关系
packageContext.addGlobalResultConfigs(results);
}
}  

  //为这个package添加全局的exception

  loadGobalExceptionMappings(newPackage, packageElement);

/**
* 从xml的元素中添加全局的结果Exception
*/
protected void loadGobalExceptionMappings(PackageConfig.Builder packageContext, Element packageElement) {
NodeList globalExceptionMappingList = packageElement.getElementsByTagName("global-exception-mappings");//查找所有的global-exception-mappings

//如果节点中global-exception-mappings的个数大于0
if (globalExceptionMappingList.getLength() > 0) {
Element globalExceptionMappingElement = (Element) globalExceptionMappingList.item(0);//获取第一个global-exception-mapping节点
List<ExceptionMappingConfig> exceptionMappings = buildExceptionMappings(globalExceptionMappingElement, packageContext);
packageContext.addGlobalExceptionMappingConfigs(exceptionMappings);//为package添加全局异常映射关系
}
}
  

  NodeList actionList = packageElement.getElementsByTagName("action");//查找所有的action节点

  //把该action元素添加到package中

  addAction(actionElement, newPackage);

/**
* 把Action放入package中
* @param actionElement action节点
* @param packageContext package上下文
* @throws ConfigurationException 异常信息
*/
protected void addAction(Element actionElement, PackageConfig.Builder packageContext) throws ConfigurationException {
String name = actionElement.getAttribute("name");//获取action的名称
String className = actionElement.getAttribute("class");//获取节点的class
String methodName = actionElement.getAttribute("method");//获取节点的method
Location location = DomHelper.getLocationObject(actionElement);//获取该节点的location
//判断location是否为空
if (location == null) {
if (LOG.isWarnEnabled()) {
LOG.warn("location null for " + className);
}
}
//如果methodName为空,则设置其为null
methodName = (methodName.trim().length() > 0) ? methodName.trim() : null;

// if there isnt a class name specified for an <action/> then try to
// use the default-class-ref from the <package/>
//该部分代码已注释
if (StringUtils.isEmpty(className)) {
// if there is a package default-class-ref use that, otherwise use action support
/* if (StringUtils.isNotEmpty(packageContext.getDefaultClassRef())) {
className = packageContext.getDefaultClassRef();
} else {
className = ActionSupport.class.getName();
}*/

} else {
if (!verifyAction(className, name, location)) {
if (LOG.isErrorEnabled())
LOG.error("Unable to verify action [#0] with class [#1], from [#2]", name, className, location.toString());
return;
}
}
//配置result
Map<String, ResultConfig> results;
try {
//创建一个ResultConfig对象的map从给定的xml元素
results = buildResults(actionElement, packageContext);
} catch (ConfigurationException e) {
throw new ConfigurationException("Error building results for action " + name + " in namespace " + packageContext.getNamespace(), e, actionElement);
}

//获取该action的拦截器
List<InterceptorMapping> interceptorList = buildInterceptorList(actionElement, packageContext);
//获取该action的异常映射
List<ExceptionMappingConfig> exceptionMappings = buildExceptionMappings(actionElement, packageContext);
//获取该action的allowed-method属性集合
Set<String> allowedMethods = buildAllowedMethods(actionElement, packageContext);
//根据解析出来的数据创建一个ActionConfig对象
ActionConfig actionConfig = new ActionConfig.Builder(packageContext.getName(), name, className)
.methodName(methodName)
.addResultConfigs(results)
.addInterceptors(interceptorList)
.addExceptionMappings(exceptionMappings)
.addParams(XmlHelper.getParams(actionElement))
.addAllowedMethod(allowedMethods)
.location(location)
.build();
//把新建的actionconfig放入packageContext中
packageContext.addActionConfig(name, actionConfig);

if (LOG.isDebugEnabled()) {
LOG.debug("Loaded " + (StringUtils.isNotEmpty(packageContext.getNamespace()) ? (packageContext.getNamespace() + "/") : "") + name + " in '" + packageContext.getName() + "' package:" + actionConfig);
}
}  

 在这个方法内部调用了buildResult(Element element, PackageConfig.Builder packageContext)方法,该方法具体如下:

/**
* 创建一个ResultConfig对象的map从给定的xml元素
*/
protected Map<String, ResultConfig> buildResults(Element element, PackageConfig.Builder packageContext) {
NodeList resultEls = element.getElementsByTagName("result");//获取节点的所有result节点

Map<String, ResultConfig> results = new LinkedHashMap<String, ResultConfig>();//创建一个result的map

/**
* 遍历result节点
*/
for (int i = 0; i < resultEls.getLength(); i++) {
Element resultElement = (Element) resultEls.item(i);//获取第i个节点

/**
* 如果该节点的父节点为给定的global-results节点,或该节点的父节点的名字等于给定的global-results节点的名字相等
*/
if (resultElement.getParentNode().equals(element) || resultElement.getParentNode().getNodeName().equals(element.getNodeName())) {
String resultName = resultElement.getAttribute("name");//获取该节点的name属性
String resultType = resultElement.getAttribute("type");//获取该节点的type属性

//如果未设置该节点的name属性,则默认为SUCCESS
if (StringUtils.isEmpty(resultName)) {
resultName = Action.SUCCESS;
}

//如果未设置该节点的type属性,我们将继承该节点的父package的类型
if (StringUtils.isEmpty(resultType)) {
//得到该节点父节点的默认result type
resultType = packageContext.getFullDefaultResultType();

//监测当前的resulttype是否有值
if (StringUtils.isEmpty(resultType)) {
//如果没值,则抛出异常
throw new ConfigurationException("No result type specified for result named '"
+ resultName + "', perhaps the parent package does not specify the result type?", resultElement);
}
}

/**
* 获取该package中的resultType
*/
ResultTypeConfig config = packageContext.getResultType(resultType);

if (config == null) {
throw new ConfigurationException("There is no result type defined for type '" + resultType
+ "' mapped with name '" + resultName + "'."
+ "  Did you mean '" + guessResultType(resultType) + "'?", resultElement);
}

//获取ResultTypeConfig的类
String resultClass = config.getClazz();

//无效的结果类型定义的结果
if (resultClass == null) {
throw new ConfigurationException("Result type '" + resultType + "' is invalid");
}

/**
* 获取该resultElement的一个resultParams的Map
*/
Map<String, String> resultParams = XmlHelper.getParams(resultElement);

if (resultParams.size() == 0) //或许,这里之后一个默认的参数
{
//如果<result ...>something</result>让后我们将添加一个'something'的 属性作为经常用到的属性
if (resultElement.getChildNodes().getLength() >= 1) {
//新建一个LinkedHashMap
resultParams = new LinkedHashMap<String, String>();

String paramName = config.getDefaultResultParam();//获取默认的result参数
//如果默认参数不为空
if (paramName != null) {
StringBuilder paramValue = new StringBuilder();//创建一个StringBuilder对象
//遍历resultElement的子节点
for (int j = 0; j < resultElement.getChildNodes().getLength(); j++) {
//如果该节点的节点类型是TEXT_NODE的话
if (resultElement.getChildNodes().item(j).getNodeType() == Node.TEXT_NODE) {
String val = resultElement.getChildNodes().item(j).getNodeValue();//获取节点值
//如果节点值不为空,则把其添加到paramValue中
if (val != null) {
paramValue.append(val);
}
}
}
String val = paramValue.toString().trim();//去掉空格
//如果其不为空,则把结果放入resultParams中
if (val.length() > 0) {
resultParams.put(paramName, val);
}
} else {
if (LOG.isWarnEnabled()) {
LOG.warn("no default parameter defined for result of type " + config.getName());
}
}
}
}

//创建一个新的参数map,如此一来,这些结果参数能覆盖配置参数
Map<String, String> params = new LinkedHashMap<String, String>();
Map<String, String> configParams = config.getParams();//获取ResultTypeConfig中的配置参数
//如果配置参数不为空,则把其放入新建立的params的MAP中
if (configParams != null) {
params.putAll(configParams);
}
//把resultParams放入params中
params.putAll(resultParams);

/**
* 创建一个新的resultConfig
*/
ResultConfig resultConfig = new ResultConfig.Builder(resultName, resultClass)
.addParams(params)
.location(DomHelper.getLocationObject(element))
.build();
//把resultConfig放入result中
results.put(resultConfig.getName(), resultConfig);
}
}
//返回result
return results;
}    

 为该action添加拦截器

/**
* 添加拦截器
* @param element 元素
* @param context package上下文
* @return
* @throws ConfigurationException
*/
protected List<InterceptorMapping> buildInterceptorList(Element element, PackageConfig.Builder context) throws ConfigurationException {
List<InterceptorMapping> interceptorList = new ArrayList<InterceptorMapping>();//创建一个拦截器Map List
NodeList interceptorRefList = element.getElementsByTagName("interceptor-ref");//获取所有的interceptor-ref

//对interceptor-ref进行遍历
for (int i = 0; i < interceptorRefList.getLength(); i++) {
Element interceptorRefElement = (Element) interceptorRefList.item(i);//获取第I个interceptor-ref节点
//如果该节点的父节点是action
if (interceptorRefElement.getParentNode().equals(element) || interceptorRefElement.getParentNode().getNodeName().equals(element.getNodeName())) {
//在全局拦截器中进行查找
List<InterceptorMapping> interceptors = lookupInterceptorReference(context, interceptorRefElement);
interceptorList.addAll(interceptors);
}
}
//返回一个拦截器列表
return interceptorList;
}

  为该action添加异常映射

/**
* 通过给定的xml节点创建一个ExceptionMapping(ResultConfig)
* @param element 节点
* @param packageContext 包
*/
protected List<ExceptionMappingConfig> buildExceptionMappings(Element element, PackageConfig.Builder packageContext) {
NodeList exceptionMappingEls = element.getElementsByTagName("exception-mapping");//获取exception-mapping元素节点

List<ExceptionMappingConfig> exceptionMappings = new ArrayList<ExceptionMappingConfig>();//创建一个异常映射list列表

/**
* 遍历exception-mapping元素节点
*/
for (int i = 0; i < exceptionMappingEls.getLength(); i++) {
Element ehElement = (Element) exceptionMappingEls.item(i);//获取第I个exception-mapping元素节点

//如果该节点的父节点为给定的global-exception-mappings,则运行
if (ehElement.getParentNode().equals(element) || ehElement.getParentNode().getNodeName().equals(element.getNodeName())) {
String emName = ehElement.getAttribute("name");//获取节点元素的name属性
String exceptionClassName = ehElement.getAttribute("exception");//获取节点元素的exception属性
String exceptionResult = ehElement.getAttribute("result");//获取接电源是的result属性

/**
* 把该节点组装成一个Map
*/
Map<String, String> params = XmlHelper.getParams(ehElement);

//判断emName是否为空
if (StringUtils.isEmpty(emName)) {
emName = exceptionResult;//若为空则把result属性的值赋给emName
}
//新建一个ExceptionMappingConfig对象
ExceptionMappingConfig ehConfig = new ExceptionMappingConfig.Builder(emName, exceptionClassName, exceptionResult)
.addParams(params)
.location(DomHelper.getLocationObject(ehElement))
.build();
exceptionMappings.add(ehConfig);
}
}

return exceptionMappings;
}    

  为该action添加allow-method

/**
* 创建allowed-method的Set
* @param element
* @param packageContext
* @return
*/
protected Set<String> buildAllowedMethods(Element element, PackageConfig.Builder packageContext) {
NodeList allowedMethodsEls = element.getElementsByTagName("allowed-methods");//获取该节点下面的所有的allowed-methods节点

Set<String> allowedMethods = null;//创建一个新的Set

//如果allowed-methods的个数大于0
if (allowedMethodsEls.getLength() > 0) {
allowedMethods = new HashSet<String>();//实例化该Set
Node n = allowedMethodsEls.item(0).getFirstChild();//获取该allowed-methods的第一个子节点
//若其不为空,即存在
if (n != null) {
String s = n.getNodeValue().trim();//获取该节点的值
if (s.length() > 0) {
allowedMethods = TextParseUtil.commaDelimitedStringToSet(s);
}
}
} else if (packageContext.isStrictMethodInvocation()) {
allowedMethods = new HashSet<String>();
}
//返回处理后的结果集
return allowedMethods;
}   

 这些配置完成之后,把该action添加到packageContext中

  然后调用:

  //为该package加载默认的action

  loadDefaultActionRef(newPackage, packageElement);

/**
* 为action加载默认的default-action-ref
* @param packageContext 包
* @param element 节点
*/
protected void loadDefaultActionRef(PackageConfig.Builder packageContext, Element element) {
NodeList resultTypeList = element.getElementsByTagName("default-action-ref");//获取该包下面的default-action-ref信息

if (resultTypeList.getLength() > 0) {
Element defaultRefElement = (Element) resultTypeList.item(0);//获取第1个该default-action-ref节点
packageContext.defaultActionRef(defaultRefElement.getAttribute("name"));//把该节点的name放入package的defaultActionRef中
}
}  

  在然后实例化该packageConfig对象,并添加到DefaultConfiguration中,返回该defaultConfiguration

  ②reloads.add(child);

  如果配置需要重新更新的话,重新加载该package节点

  ③loadExtraConfiguration(doc);

  该方法未执行任何操作,该方法内容具体如下:

/**
* 运行子类加载document中的其他信息
* @param doc The configuration document
*/
protected void loadExtraConfiguration(Document doc) {
// no op
}   

  ③loadExtraConfiguration(doc);//这三个方法没什么好介绍的

  ④reloadRequiredPackages(reloads);

  ⑤loadExtraConfiguration(doc);

  至此,loadPackages方法执行结束

  3:StrutsXmlConfigurationProvider(struts-plugin.xml)

  同2:

  4:StrutsXmlConfigurationProvider(struts.xml)

  同2:

  5:LegacyPropertiesConfigurationProvider

  同1:

  6:用户配置

  具体情况具体分析

  7:web.xml的filter中配置的参数

  该方法是一个空实现

  8:BeanSelectionProvider

  该类中的该方法是一个空实现

  19)packageProviders.add((PackageProvider)containerProvider);

  把解析完之后的packageProvider放入packageProviders的list中

  20)Set<String> packageProviderNames = container.getInstanceNames(PackageProvider.class);

  根据类型来取得该类型的实例对象名称集合(适用于同一个类型创建了多个不同名称的对象)

  21)PackageProvider provider = container.getInstance(PackageProvider.class, name);

  22)provider.init(this);

  23)provider.loadPackages();

  24)packageProviders.add(provider);

  25)rebuildRuntimeConfiguration();

  27)return packageProviders;

  这些代码,暂时未分析

  ②Container container = config.getContainer();

  获取DefaultConfiguration实体对象的Container对象(此时的Container对象是一个ContainerImpl对象)

  ③boolean reloadi18n = Boolean.valueOf(container.getInstance(String.class, StrutsConstants.STRUTS_I18N_RELOAD));

  获取是否配置了国际化

  ④LocalizedTextUtil.setReloadBundles(reloadi18n);

  定义是否需要重新装载资源绑定

4、加载完配置文件之后执行的操作

  一:container.inject(this);

 

  二:init_CheckConfigurationReloading(container);

/**
* 在FileManager中设置是否需要重新加载
* @param container
*/
private void init_CheckConfigurationReloading(Container container) {
//此时FileManager对象的实体是DefaultFileManager
FileManager fileManager = container.getInstance(FileManager.class);
fileManager.setReloadingConfigs("true".equals(container.getInstance(String.class, StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD)));
} 

  三:init_CheckWebLogicWorkaround(container);

/**
* 该方法具体内容暂时未分析
* @param container
*/
private void init_CheckWebLogicWorkaround(Container container) {
// test whether param-access workaround needs to be enabled
if (servletContext != null && servletContext.getServerInfo() != null
&& servletContext.getServerInfo().contains("WebLogic")) {
if (LOG.isInfoEnabled()) {
LOG.info("WebLogic server detected. Enabling Struts parameter access work-around.");
}
paramsWorkaroundEnabled = true;
} else {
paramsWorkaroundEnabled = "true".equals(container.getInstance(String.class,
StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND));
}
}

5、介绍StrutsPrepareAndExecuteFilter中剩余的部分

  prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);实例化一个prepare方法

  这里的PrepareOperations类的构造方法如下:

/**
* PrepareOperations的构造方法
* @param servletContext
* @param dispatcher
*/
public PrepareOperations(ServletContext servletContext, Dispatcher dispatcher) {
this.dispatcher = dispatcher;//实例化该类的内部变量dispatcher
this.servletContext = servletContext;//实例化该类内部的变量servletContext
} 

  execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);实例化一个execute方法

  这里的ExecuteOperations类的构造方法如下:

/**
* ExecuteOperations的构造方法
* @param servletContext servletContext实例
* @param dispatcher dispatcher实例
*/
public ExecuteOperations(ServletContext servletContext, Dispatcher dispatcher) {
this.dispatcher = dispatcher;//实例化该类的内部变量dispatcher
this.servletContext = servletContext;//实例化该类内部的变量servletContext
}

  this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);执行buildExcludedPatternsList方法

  该方法的具体含义目前不是很了解

  postInit(dispatcher, filterConfig);//执行postInit方法

  调用的StrutsPrepareAndExecuteFilter类中的postInit(Dispatcher dispatcher, FilterConfig filterConfig)方法如下:

/**
* Callback for post initialization
*/
protected void postInit(Dispatcher dispatcher, FilterConfig filterConfig) {
}

至此,struts2框架初始化结束
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  struts2 源码 初始化