spring加载及和struts的结合

 web应用中spring提供了几种加载方式:
1.在web.xml中配置:
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
    <servlet-name>context</servlet-name>
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
2.在web.xml中配置:
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

1和2两种方式,实质是一样的,因为在他们各自的初始化方法中,调用的是一样的创建spring容器的方法
这是1中的:
public void init() throws ServletException {
       contextLoader = createContextLoader();
       contextLoader.initWebApplicationContext(getServletContext());
      }
这是2中的:
public void contextInitialized(ServletContextEvent event) {
       contextLoader = createContextLoader();
       contextLoader.initWebApplicationContext(event.getServletContext());
      }
所以这两种加载spring容器的方法本质上一样,spring容器初始化完后,就放到servletContext中。
其key值为:WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
我们如果要使用WebApplicationContext则需要从ServletContext取出,Spring提供了一个WebApplicationContextUtils类,可以方便的取出

WebApplicationContext,只要把ServletContext传入就可以了。
获得applicationContext 方法:
ServletContext context = getServletContext();

WebApplicationContext applicationContext  = WebApplicationContextUtils
     .getWebApplicationContext(context);
  
 DataSource dataSource=(DataSource)applicationContext.getBean("dataSource");
这个方便的类是针对以上面的方式创建的spring容器而用的。


3.在struts.xml中配置加载spring的插件:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
  <set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml" />
</plug-in>
这种方法初始化的spring容器,也放在servletContext中,
其key值为:
ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX+ModuleConfig.getPrefix()(具体请查看源代码)。


4.在web.xml中配置:
<servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/applicationContext</param-value>
        </init-param>
    </servlet>

获得applicationContext 方法:
ServletContext context = getServletContext();
 
  XmlWebApplicationContext applicationContext = (XmlWebApplicationContext) context.getAttribute

("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet");


  DataSource dataSource=(DataSource)applicationContext.getBean("dataSource");

************************************************************************************
spring和struts的结合方式。
两者的结合可以有以下三种方式:
1.使用 Spring 的 ActionSupport 类整合 Structs
2.使用 Spring 的 DelegatingRequestProcessor 覆盖 Struts 的 RequestProcessor
3.将 Struts Action 管理委托给 Spring 框架


第1种方式用我们自己的Action继承ActionSupport。这种方式只是方便了我们在action中获得spring容器对象,在ActionSupport中提供了getWebApplicationContext()方法。获得了spring容器后,就可以享用spring容器中的bean了。


第2种方式和第3种方式,都是把Struts Action 管理委托给 Spring 框架 ,只是委托方式不一样。
第2种方式使用 Spring 的 DelegatingRequestProcessor 覆盖 Struts 的 RequestProcessor。而DelegatingRequestProcessor 所做的工作,也就是,获得spring容器,获得被spring容器管理的真正action。

第3种方式在struts.xml中的action配置中配置:
 <action    path="/searchSubmit"  type="org.springframework.web.struts.DelegatingActionProxy"> ...
而这个代理action:DelegatingActionProxy所做的工作也是,获得spring容器,获得被spring容器管理的真正action。

这3种结合方式,都需要获得spring容器,而上面也说到,spring容器的创建也有三种方式(本质上是三种,目前为止我知道的)。
三种创建spring容器的方式,都在他们创建完spring容器后,将spring容器,放到servletContext对象中,但key值不一样。这也就决定了获得spring容器的方法是不同的。

 

在这三种spring和struts的结合方式中都通过以下方式获得spring容器:
DelegatingActionUtils.findRequiredWebApplicationContext(ActionServlet actionServlet, ModuleConfig moduleConfig)
而这种方法会先去寻找以struts插件形式,创建的spring容器。也就是以上面spring加载方式3中的key值到servletContext中找。
如果找不到,再调用WebApplicationContextUtils.getWebApplicationContext(ServletContext context)方法获得spring容器。

由WebApplicationContextUtils类获得的spring容器和由DelegatingActionUtils类获得的spring容器是不同的。这两种获得方法是针对不同的spring容器创建方法的。前者对应的创建方法是上面spring创建方法的第1,2两种。后者对应的创建方法是上面spring创建方法的第3种。


结论:spring和struts的三种结合方式中,会先去寻找以struts插件形式,创建的spring容器。所以我们在struts中配置spring的加载插件,可以满足这三种结合方式。在找不到以struts插件形式,创建的spring容器后,会去找以ContextLoaderListener或ContextLoaderServlet创建的spring容器,所以,不管以那种方式创建的spring容器都能满足spring和struts的三种结合方式。(第4种创建spring容器方式除外)。

这只是自己的分析,还没实践,需要研究。

 

发布了38 篇原创文章 · 获赞 11 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章