struts-default.xml

这个文件是struts2框架默认加载的配置文件。它定义struts2一些核心的bean和拦截器。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!--struts2中工厂bean的定义-->
<bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" />
<bean type="com.opensymphony.xwork2.ObjectFactory" name="struts" class="org.apache.struts2.impl.StrutsObjectFactory" />
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="xwork" class="com.opensymphony.xwork2.DefaultActionProxyFactory"/>
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="struts" class="org.apache.struts2.impl.StrutsActionProxyFactory"/>
<!--类型检测bean的定义-->
<bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="tiger" class="com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer"/>
<bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="notiger" class="com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer"/>
<bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="struts" class="com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer"/>
<!--文件上传bean的定义-->
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts" class="org.apache.struts2.dispatcher.mapper.DefaultActionMapper" />
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="composite" class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" />
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful" class="org.apache.struts2.dispatcher.mapper.RestfulActionMapper" />
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful2" class="org.apache.struts2.dispatcher.mapper.Restful2ActionMapper" />
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="struts" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default" optional="true"/>
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="jakarta" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default" optional="true" />
<!--标签库bean的定义-->
<bean type="org.apache.struts2.views.TagLibrary" name="s" class="org.apache.struts2.views.DefaultTagLibrary" />
<!--一些常用视图bean的定义-->
<bean class="org.apache.struts2.views.freemarker.FreemarkerManager" name="struts" optional="true"/>
<bean class="org.apache.struts2.views.velocity.VelocityManager" name="struts" optional="true" />
<bean class="org.apache.struts2.components.template.TemplateEngineManager" />
<bean type="org.apache.struts2.components.template.TemplateEngine" name="ftl" class="org.apache.struts2.components.template.FreemarkerTemplateEngine" />
<bean type="org.apache.struts2.components.template.TemplateEngine" name="vm" class="org.apache.struts2.components.template.VelocityTemplateEngine" />
<bean type="org.apache.struts2.components.template.TemplateEngine" name="jsp" class="org.apache.struts2.components.template.JspTemplateEngine" />
<!--类型转换bean的定义-->
<bean type="com.opensymphony.xwork2.util.XWorkConverter" name="xwork1" class="com.opensymphony.xwork2.util.XWorkConverter" />
<bean type="com.opensymphony.xwork2.util.XWorkConverter" name="struts" class="com.opensymphony.xwork2.util.AnnotationXWorkConverter" />
<bean type="com.opensymphony.xwork2.TextProvider" name="xwork1" class="com.opensymphony.xwork2.TextProviderSupport" />
<bean type="com.opensymphony.xwork2.TextProvider" name="struts" class="com.opensymphony.xwork2.TextProviderSupport" />
<!-- Struts2中一些可以静态注入的bean,也就是不需要实例化的 -->
<bean class="com.opensymphony.xwork2.ObjectFactory" static="true" />
<bean class="com.opensymphony.xwork2.util.XWorkConverter" static="true" />
<bean class="com.opensymphony.xwork2.util.OgnlValueStack" static="true" />
<bean class="org.apache.struts2.dispatcher.Dispatcher" static="true" />
<bean class="org.apache.struts2.components.Include" static="true" />
<bean class="org.apache.struts2.dispatcher.FilterDispatcher" static="true" />
<bean class="org.apache.struts2.views.util.ContextUtil" static="true" />
<bean class="org.apache.struts2.views.util.UrlHelper" static="true" />
<!-- 定义Struts2默认包-->
<package name="struts-default" abstract="true">
<!-- 结果类型的种类-->
<result-types>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
<result-type name="redirect-action" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="plaintext" class="org.apache.struts2.dispatcher.PlainTextResult" />
</result-types>
<!--struts2中拦截器的定义-->
<interceptors>
<!--实现在不同请求中相似参数别名的准换-->
<interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
<!--与Spring整合时自动装配的拦截器-->
<interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
<!--构建一个action链,使当前action可以访问前一个action,与<result-type="chain" />配合使用-->
<interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
<!--负责类型转换的拦截器-->
<interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
<!--使用配置的name,value来是指cookies -->
<interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>
<!--负责创建httpSession-->
<interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
<!--输出调试信息-->
<interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
<!--扩展引用-->
<interceptor name="externalRef" class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>
<!--后台执行action负责发送等待画面给用户-->
<interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
<!--异常处理-->
<interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
<!--文件上传,解析表单域的内容-->
<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
<!--支持国际化-->
<interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
<!--日志记录-->
<interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<!--模型拦截器,当action实现了ModelDriven接口时,负责把getModel的结果放入valueStack中-->
<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
<!--有生命周期的ModelDriven-->
<interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
<!--负责解析请求中的参数,并赋值给action中对应的属性-->
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
<!--实现该Preparable接口的action,会调用拦截器的prepare方法-->
<interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
<!--负责将action 标签下的param参数值传递给action实例-->
<interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
<!--范围转换-->
<interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
<!--用于访问Servlet API-->
<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
<interceptor name="sessionAutowiring" class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>
<!--输出action执行时间-->
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<!--防止表单重复提交-->
<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
<!--与token拦截器相似,只是把token保存到HttpSession-->
<interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
<!--负责表单字段的验证 *-validation.xml-->
<interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
<!--负责执行action的validate()-->
<interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
<!--存储和重新获取Action 消息/错误/字段错误为Action,实现ValidationAware接口到seesion-->
<interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
<!--添加自动checkbox处理代码,这样检探测checkbox和添加它作为一个参数使用默认值(通常’false’).使用一个指定名字隐藏字段探测没提交的checkbox-->
<interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
<interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
<!--JAAS服务拦截器-->
<interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
<!-- 一个基本的拦截器栈 -->
<interceptor-stack name="basicStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
</interceptor-stack>
<!-- 简单的validtion和webflow栈 -->
<interceptor-stack name="validationWorkflowStack">
<interceptor-ref name="basicStack"/>
<interceptor-ref name="validation"/>
<interceptor-ref name="workflow"/>
</interceptor-stack>
<!-- 文件上传的拦截器栈 -->
<interceptor-stack name="fileUploadStack">
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="basicStack"/>
</interceptor-stack>
<!-- model-driven 栈 -->
<interceptor-stack name="modelDrivenStack">
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="basicStack"/>
</interceptor-stack>
<!-- action链的拦截器栈 -->
<interceptor-stack name="chainStack">
<interceptor-ref name="chain"/>
<interceptor-ref name="basicStack"/>
</interceptor-stack>
<!-- i18n 拦截器栈 -->
<interceptor-stack name="i18nStack">
<interceptor-ref name="i18n"/>
<interceptor-ref name="basicStack"/>
</interceptor-stack>
<!-- 结合preparable和ModenDriven拦截器-->
<interceptor-stack name="paramsPrepareParamsStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="params"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel</param>
</interceptor-ref>
</interceptor-stack>
<!--定义默认的拦截器栈 -->
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="debugging"/>
<interceptor-ref name="profiling"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>
<interceptor-stack name="completeStack">
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
<interceptor-stack name="executeAndWaitStack">
<interceptor-ref name="execAndWait">
<param name="excludeMethods">input,back,cancel</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="execAndWait">
<param name="excludeMethods">input,back,cancel</param>
</interceptor-ref>
</interceptor-stack>
<interceptor name="external-ref" class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>
<interceptor name="model-driven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
<interceptor name="static-params" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
<interceptor name="scoped-model-driven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
<interceptor name="servlet-config" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
<interceptor name="token-session" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
</interceptors>
<!--定义默认拦截器为"defaultStack"-->
<default-interceptor-ref name="defaultStack"/>
</package>
</struts> 
在这个配置文件中,我们可以看到,Struts2的XML自身所支持的节点和子节点并不是很多,大致来说,这些节点可以分成基本配置定义和Runtime配置定义。 
基本配置定义 
基本配置定义,主要是针对在Struts2内部所使用的各种元素的声明。这些声明往往规定了Struts2内部的一些行为特征。 
例如,配置文件中的<bean>节点,被用于定义Struts2中所使用的接口和实现类,通过Struts2内部实现的IoC,你就可以在不同的实现类之间进行切换。 
再例如,配置文件中的<result-type>节点和<interceptor>节点。他们用于定义Struts2中所支持的所有的Result类型和拦截器,这些定义和声明,将在Runtime的配置定义中被引用。 
我之所以把配置文件中的这些节点单独列出来,作为一个种类,是因为这些节点是不可省略的,也是无法简化的。所以,如果我们试图在Struts2中简化配置,我们就需要在Runtime配置定义中下功夫,而这些基本配置定义,我们可以认为是Runtime配置定义的基础。 
Runtime配置定义 
Runtime配置定义,主要指的的是对Struts2运行过程中,具体的某个Action的行为的指定。这些指定主要通过<package>节点中的<action>节点来完成。 
仔细翻阅<action>节点,我们可以发现,它是URL与Action之间沟通的桥梁,也就是说,它定义了URL与Action之间的对应关系。同时,它还指定了Action在执行过程中的具体行为,包括Action执行的时候使用什么样的拦截器、Action执行完毕后,转向到什么样的Result等等。 
Runtime配置定义是可以简化的,Struts2中提供了很多种简化配置的方式,这个在之后的文章中会详细提到。 

模块化管理配置文件
一旦项目变得很大,项目中同时也并不采取什么简化配置的措施,那么在默认情况下,配置文件就会变得很大而不易于维护。这个时候,对于配置文件的模块化管理的需求就显现出来。Struts2提供了两种方式对配置文件进行模块化管理。
plugin机制 
Struts2有plugin的机制,有关plugin的具体的知识,请参考我的另外一篇专栏文章:《深入plugin》 ——  http://www.javaeye.com/wiki/struts2/1333-deep-into-plugin。在这里,我也就不详细介绍了。 
在每个plugin中,都会有一个叫做struts-plugin.xml的配置文件,这个配置文件的格式与struts-default.xml的格式是相同的。可以在其中做出任何的Struts2的定义和配置。我们知道,Struts2的配置文件的加载顺序,是按照以下的顺序来: 

Struts2 Referece 写道
1. struts-default.xml (bundled in the Core JAR)
2. struts-plugin.xml (as many as can be found in other JARs)
3. struts.xml (provided by your application)

所以,struts-plugin.xml中的配置的效果实际上与struts-default.xml的效果是相同的。这样,通过各种各样不同的plugin,就等于将Struts2的配置,按照plugin的功能不同而分开了。从而起到了配置文件模块化管理的效果。
使用include节点 
plugin中的配置文件,实际上是位于classpath的JAR包中的,那么我们在项目中,如何对一个庞大的配置文件进行拆分呢?在Struts2中,可以使用include节点对所有的Struts2配置文件进行拆分和模块化管理。例如: 
Xml代码 
1.<struts> 
2. 
3.    <include file="struts-default.xml"/> 
4.    <include file="web/struts-config.xml"/> 
5.    <include file="web/struts-action.xml"/> 
6.      
7.</struts> 
<struts>
    <include file="struts-default.xml"/>
    <include file="web/struts-config.xml"/>
    <include file="web/struts-action.xml"/>
 
</struts>
其中,file所指定的文件是相对于classpath的相对目录中的文件。而每个配置文件的格式与struts-default.xml的格式也是相同的。
通过include节点,我们就可以对一个比较大的配置文件按照功能和模块进行拆分,这在一个大型的团队开发中,是相当有意义的。 
简单的IoC
在基本配置定义中,有两个很常用的节点:<bean>和<constant>。在系统启动的时候,Struts2会根据配置文件中这些<bean>和<constant>节点的定义进行加载,并初始化成为Struts2的默认行为。这种初始化的行为,非常类似于Spring中的依赖注入(IoC),从而使得你不再需要担心这些对象在运行时的创建和销毁,所有的工作都由Struts2内部的机制实现。接下来我们就来看看Struts2是如何实现IoC的。

Struts2 Reference 写道
Internally, the framework uses its own dependency injection container that is very similar to Google Guice (both were originally developed by Bob Lee)

这是来自于Struts2的Reference对它自身的IoC的描述。如果熟悉Guice的朋友一定知道,Guice的实现使用了Annotation的方式进行,而整个依赖注入的实现,是通过一个内部的容器类进行的。Struts2的依赖注入,与Guice的机制完全一致。根据注入的内容的不同,Struts2的IoC可以对容器中的对象的依赖关系进行管理,也可以注入一些静态变量。
bean注入 
对于bean的注入,对应于XML中的bean的节点声明。我把其中的机制分成了3个部分: 
1. 容器中对象的声明 

Xml代码
1.<bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" /> 
2.<bean type="com.opensymphony.xwork2.ObjectFactory" name="struts" class="org.apache.struts2.impl.StrutsObjectFactory" /> 
<bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" />
<bean type="com.opensymphony.xwork2.ObjectFactory" name="struts" class="org.apache.struts2.impl.StrutsObjectFactory" />
这点没什么好说的,在struts.xml中,你可以为某个接口声明它所对应的实现类。 
name属性 
你可以声明多个实现类,使用name属性进行区分。在注入的时候,将使用这个属性的值作为接口实现类的选择。 
required属性 
你还可以通过required属性,来指定是否在运行时必不可少的注入。如果reqired被设置成false,那么当不存在相应的接口定义时,注入将被忽略。 
static属性 
在XML的定义中,还可以使用static属性。如果static属性被设置成true,那么注入将针对bean中的static方法和static属性进行。 
2. 在代码中使用Annotation进行注入 

Java代码
<a href="mailto:1.@Inject(" xwork'="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0px; padding: 0px; color: rgb(66, 133, 244); background: none; border: none; max-width: 100%;">1.@Inject("xwork")  
2.protected ObjectFactory objectFactory;  
3. 
4.public LightURLUnknownHandler(@Inject ObjectFactory objectFactory) {  
5.    this.objectFactory = objectFactory;  
6.}  
7. 
8.@Inject 
9.public void setObjectFactory(ObjectFactory factory) {  
10.    this.objectFactory = factory;  
11.}  
12. 
13.@Inject(required=false)  
14.public void setUnknownHandler(UnknownHandler handler) {  
15.    this.unknownHandler = handler;  
16.} 
@Inject("xwork")
protected ObjectFactory objectFactory;
public LightURLUnknownHandler(@Inject ObjectFactory objectFactory) {
    this.objectFactory = objectFactory;
}
@Inject
public void setObjectFactory(ObjectFactory factory) {
    this.objectFactory = factory;
}
@Inject(required=false)
public void setUnknownHandler(UnknownHandler handler) {
    this.unknownHandler = handler;
}

在代码中,使用@Inject这样一个Annotation进行对象依赖注入。在上面的例子中,我们可以看到,@Inject这个Annotation,可以作用在属性上,也可以作用在方法上,甚至可以作用在方法的参数上。
在默认情况下,如果@Inject不指定value,那么XML配置定义中的name="default"或者name=""的实现类定义将被注入。 
那么,在struts-default.xml中,Struts2到底选择了那些实现类,作为Struts2或者XWork内部接口的默认实现类呢?默认情况下,struts-default.xml中定义的bean的name="struts"的将被作为默认的接口实现类被注入。这些默认行为,是由org.apache.struts2.config.BeanSelectionProvider所决定的,有兴趣的读者可以参阅这个类的源码。 
3. 内部的Container机制完成一切背后工作 
上面看到的,是现象。在内部,Struts2通过一个Container来实现所有的注入机制。 

Java代码
1.public interface Container extends Serializable {  
2. 
3.  /** 
4.   * Default dependency name. 
5.   */ 
6.  String DEFAULT_NAME = "default";  
7. 
8.  /** 
9.   * Injects dependencies into the fields and methods of an existing object. 
10.   */ 
11.  void inject(Object o);  
12. 
13.  /** 
14.   * Creates and injects a new instance of type {@code implementation}. 
15.   */ 
16.  <T> T inject(Class<T> implementation);  
17. 
18.  /** 
19.   * Gets an instance of the given dependency which was declared in 
20.   * {@link com.opensymphony.xwork2.inject.ContainerBuilder}. 
21.   */ 
22.  <T> T getInstance(Class<T> type, String name);  
23. 
24.  /** 
25.   * Convenience method.&nbsp;Equivalent to {@code getInstance(type, 
26.   * DEFAULT_NAME)}. 
27.   */ 
28.  <T> T getInstance(Class<T> type);  
29.    
30.  /** 
31.   * Gets a set of all registered names for the given type 
32.   * @param type The instance type 
33.   * @return A set of registered names 
34.   */ 
35.  Set<String> getInstanceNames(Class<?> type);  
36. 
37.  /** 
38.   * Sets the scope strategy for the current thread. 
39.   */ 
40.  void setScopeStrategy(Scope.Strategy scopeStrategy);  
41. 
42.  /** 
43.   * Removes the scope strategy for the current thread. 
44.   */ 
45.  void removeScopeStrategy();  
46.} 
public interface Container extends Serializable {
  /**
   * Default dependency name.
   */
  String DEFAULT_NAME = "default";
  /**
   * Injects dependencies into the fields and methods of an existing object.
   */
  void inject(Object o);
  /**
   * Creates and injects a new instance of type {@code implementation}.
   */
  <T> T inject(Class<T> implementation);
  /**
   * Gets an instance of the given dependency which was declared in
   * {@link com.opensymphony.xwork2.inject.ContainerBuilder}.
   */
  <T> T getInstance(Class<T> type, String name);
  /**
   * Convenience method.&nbsp;Equivalent to {@code getInstance(type,
   * DEFAULT_NAME)}.
   */
  <T> T getInstance(Class<T> type);
 
  /**
   * Gets a set of all registered names for the given type
   * @param type The instance type
   * @return A set of registered names
   */
  Set<String> getInstanceNames(Class<?> type);
  /**
   * Sets the scope strategy for the current thread.
   */
  void setScopeStrategy(Scope.Strategy scopeStrategy);
  /**
   * Removes the scope strategy for the current thread.
   */
  void removeScopeStrategy();
}

在系统启动的时候,这个Container的实现类就会工作,把XML中定义的内容进行注入。有兴趣的读者可以继续探寻这个接口的实现类:com.opensymphony.xwork2.inject.ContainerImpl。
静态变量(Constant)的注入 
@Inject这个Annotation不仅能够对接口的实现类进行注入,也能够对静态变量进行注入。 
有关静态变量的声明和注入,在我的另外一篇专栏文章中已经详细阐述:《深入plugin》 ——  http://www.javaeye.com/wiki/struts2/1333-deep-into-plugin。在这里,我也就不详细介绍了。 
package节点详解
package节点是整个配置的核心部分。每个package,从语义上讲,其实代表了每一个独立的模块。在这个模块中,你可以定义隶属于这个模块的行为方式,而与其他的模块没有关系。所以,每个package都有独立的interceptor、result-type和action的定义,绝大多数的Runtime配置定义都是通过package节点实现的。接下来我们就来详细讨论一下package中的属性和子节点。
基本属性 
1. name 
name属性为每个package设置一个唯一的标识,这个标识在所有的package定义中不能重复。 
2. abstract 
标识这个package的定义是一个抽象定义,也就是允许他仅包含声明式的定义,而不需要在package定义中包含action的定义。 
3. extends 
通过使用extends,你可以指定本package继承另外一个package的所有的配置。当某个package继承了另外一个package的所有配置,那么你就无需对父package中已经声明过的配置定义做再次的定义。 
同时,如果重复定义父package中已声明过的配置定义,那么这些重复定义声明将覆盖父package中的相关定义。 
4. namespace 

Struts2 Reference 写道
The namespace attribute subdivides action configurations into logical modules, each with its own identifying prefix. Namespaces avoid conflicts between action names. Each namespace can have its own "menu" or "help" action, each with its own implementation.

这段来自Struts2的Reference的引用,基本上阐明了namespace的作用:对于action配置进行逻辑划分。
如果我们不为package节点指定namespace,Struts2默认使用一个空字符串作为默认的namespace。当然,也可以使用"/"等字符串来表示namespace。 
Struts2在根据URL进行寻址的时候,使用以下的步骤: 
1) 根据URL进行Namespace和ActionName的计算 
2) 根据计算的得到的Namespace和ActionName查找package节点中相应配置 
3) 如果查找失败,则查找Namespace为空,ActionName为整个URL的配置 
有关上述3点的详细信息,请参考Struts2的Reference:http://struts.apache.org/2.0.14/docs/namespace-configuration.html 
result-types节点 
在result-types节点中,我们可以声明在本package中所支持的Result类型。这些Result类型,将在action节点中被引用到。 
interceptors节点 
在interceptors节点中有两类节点:<interceptor>和<interceptor-stack>。这两个节点都用于声明拦截器。前者的作用,是真正定义一个拦截器。而后者则通过引用已经定义的拦截器,指定他们的执行顺序。 
当我们在试图在Action中引用拦截器时,我们实际上是为某个Action指定需要执行哪些拦截器,并且为这些拦截器指定执行顺序。所以Action所引用的,是某个<interceptor-stack>中的定义。 
缺省配置指向 
为了简化配置,我们可以在package节点中指定本package内的缺省配置指向。这可以通过<default-interceptor-ref>、<default-action-ref>、<global-results>等子节点来完成。 
action节点 
action节点是所有的Runtime配置的核心内容。它的主要作用就是指定URL与Action之间的映射关系。同时,在action节点中你也可以指定action执行时的相关配置,例如action所引用的interceptor等。 
参考文档 
上面所有的内容,实际上我只是做了一些简单的概括和归纳,至于每个节点语义和每个节点中具体属性的使用,我认为还是需要参考Struts2的Reference,因为Reference的讲解比任何教程都来的详细和正确,所以希望大家在了解了这些配置的基本分类之后,重新阅读Struts2的Reference的相关章节,从而更加深刻的理解Struts2配置文件的方方面面:http://struts.apache.org/2.0.14/docs/configuration-elements.html
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zzr173/archive/2009/01/21/3847356.aspx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值