struts2学习笔记之spring整合

简介: 一、整合步骤:1 配置classpath,将struts-spring-plugin.jar和spring.jar添加进去    如果少了spring.jar将报错,提示找不到相关类定义。2 在web.
一、整合步骤:
1 配置classpath,将struts-spring-plugin.jar和spring.jar添加进去
   如果少了spring.jar将报错,提示找不到相关类定义。

2 在web.xml中配置spring
<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:META-INF/spring/**/*-context.xml</param-value>
  </context-param>
  使用ContextLoaderListener
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListenre</listener-class>
  </listener>
   
3  配置application-Context.xml 
  如:
    <bean id="userService" class="service.impl.UserServiceImpl">
       ...
    </bean>

4 在struts的action类中使用service
  private UserService userService;
  public void setUserService(UserService userService){
     this.userService = userService;
  }

  通过以上方式,便可以直接在action中直接使用service进行逻辑处理。
  
二、原理分析:
1  spring的ApplicationContext的加载:
       加载方式通常有两种:
       A  通过ContextLoaderListener,如前面例子所示;但要求Web服务器支持servlet2.3以上的规范
       B  通过ContextLoaderServlet,不需要服务器支持servlet2.3以上规范:
          <context-param>... 配置spring配置文件位置,如上示例
          <servlet>
             <servlet-name>context</servlet-name>
             <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
             <load-on-startup>1</load-on-startup>    
            <!--load-on-startup大于等于0时表示服务器启动时将实例化该servlet并调用init方法,数字表示优先级,越小则初始化的时机越先 -->
          </servlet>
          然而spring的加载时机在listener方式中是更靠前的。

    ContextLoaderListener与ContextLoaderServlet的实现原理是一样的,其都是通过ContextLoader来加载ApplicationContext:

       this.contextLoader = createContextLoader();
       this.contextLoader.initWebApplicationContext(event.getServletContext());

       而ContextLoader中加载spring配置的代码如下:
       this.context = createWebApplicationContext(servletContext, parent);
       servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
       可以看到,loader对象将加载后的WebAppApplication对象放入了servletContext中(application级别的内存对象),以WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE为key来访问。

2  struts2中如何与spring协作:
       struts2加载配置文件的顺序为 struts-default.xml/struts-plugin.xml/struts.xml,因此插件中的配置文件优先级比默认配置文件中要高;
       struts中的Action、Result、拦截器实例均通过以 struts.objectFactory常量指定的实现类来创建,该类需要继承于com.opensymphony.xwork2.ObjectFactory
        查看struts-default.xml可以找到:
 <bean type="com.opensymphony.xwork2.ObjectFactory" name="struts" class="org.apache.struts2.impl.StrutsObjectFactory" />

      而struts.objectFactory的默认值便是struts,因此默认情况下struts使用org.apache.struts2.impl.StrutsObjectFactory来创建Action、拦截器等实例

      再看看struts-spring-plugin.jar中的xml配置:
      <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
        <!--  Make the Spring object factory the automatic default -->
        <constant name="struts.objectFactory" value="spring" />
       于是,在加载了spring插件之后,struts.objectFactory将采用org.apache.struts2.spring.StrutsSpringObjectFactory
       查看StrutsSpringObjectFactory的构造方法:  
//获得原先加载的spring的context
           Object rootWebApplicationContext =  servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); 
             ...
           ApplicationContext appContext = (ApplicationContext) rootWebApplicationContext;
           this.setApplicationContext(appContext);   //注入到当前实例
       该类继承了SpringObjectFactory,查看源码发现其创建bean的时候都使用了属于spring的名为 autoWiringFactory的对象向bean注入了属性,正如上面看到的
       action中的setUserService被用于注入service;

      此外还需要考虑一个autowireStrategy参数,其指定了自动装配的策略(属于spring的范畴),默认是name即按名称注入。

     可以通过修改struts.objectFactory.spring.autoWire的常量值来改变autowireStrategy,可选的值包括:name/type(按类型)/auto(由spring自动检测)/constructor(构造器注入)


三、 另一种整合方式
     此处介绍一下另外一种整合的方式:
     1  action类与开头例子一致;
     2  struts.xml中配置action的class属性值为spring配置文件中的bean名;
     3  spring配置对应名称的bean,class指向真实的action类,此时action更加直观的由spring管理,获得了更高的可配置性。

     查看SpringObjectFactory中的buildBean方法:
 //当spring的context中存在bean名的定义时,直接使用spring管理的方式来构造对象,否则走混合注入的方式(开头例子所采用,也是推荐使用的)
      if (appContext.containsBeanDefinition(beanName)) {
            o = appContext.getBean(beanName);
        } else {
            Class beanClazz = getClassInstance(beanName);
            o = buildBean(beanClazz, extraContext);
        }
   怎么样,一目了然了吧

  然而这样的方式在大多数情况下显得很臃肿:action需要配置多处;另外spring部分的配置稍显繁杂。因此一般不推荐该整合方式,这里仅仅是介绍罢了。
     
       
  
       




     


      

 
 
img_9b09a36f6de95886f52ce82fa1e89c88.jpe

作者: zale

出处: http://www.cnblogs.com/littleatp/, 如果喜欢我的文章,请关注我的公众号

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接  如有问题, 可留言咨询.

目录
相关文章
|
1月前
|
搜索推荐 JavaScript Java
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。
|
8月前
|
监控 Java 应用服务中间件
微服务——SpringBoot使用归纳——为什么学习Spring Boot
本文主要探讨为什么学习Spring Boot。从Spring官方定位来看,Spring Boot旨在快速启动和运行项目,简化配置与编码。其优点包括:1) 良好的基因,继承了Spring框架的优点;2) 简化编码,通过starter依赖减少手动配置;3) 简化配置,采用Java Config方式替代繁琐的XML配置;4) 简化部署,内嵌Tomcat支持一键式启动;5) 简化监控,提供运行期性能参数获取功能。此外,从未来发展趋势看,微服务架构逐渐成为主流,而Spring Boot作为官方推荐技术,与Spring Cloud配合使用,将成为未来发展的重要方向。
302 0
微服务——SpringBoot使用归纳——为什么学习Spring Boot
|
5月前
|
安全 Java 数据库
Spring Boot 框架深入学习示例教程详解
本教程深入讲解Spring Boot框架,先介绍其基础概念与优势,如自动配置、独立运行等。通过搭建项目、配置数据库等步骤展示技术方案,并结合RESTful API开发实例帮助学习。内容涵盖环境搭建、核心组件应用(Spring MVC、Spring Data JPA、Spring Security)及示例项目——在线书店系统,助你掌握Spring Boot开发全流程。代码资源可从[链接](https://pan.quark.cn/s/14fcf913bae6)获取。
670 2
|
7月前
|
Java Spring
Spring框架的学习与应用
总的来说,Spring框架是Java开发中的一把强大的工具。通过理解其核心概念,通过实践来学习和掌握,你可以充分利用Spring框架的强大功能,提高你的开发效率和代码质量。
184 20
|
Java Maven Spring
springboot学习一:idea社区版本创建springboot项目的三种方式(第三种为主)
这篇文章介绍了在IntelliJ IDEA社区版中创建Spring Boot项目的三种方法,特别强调了第三种方法的详细步骤。
10682 0
springboot学习一:idea社区版本创建springboot项目的三种方式(第三种为主)
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
275 9
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
826 2
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
833 1
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
前端开发 Java 数据库
SpringBoot学习
【10月更文挑战第7天】Spring学习
177 9
|
XML Java 数据格式
Spring学习
【10月更文挑战第6天】Spring学习
114 1