Struts1.X与Spring集成——第二种方案

上篇博客介绍了Struts1.X与Spring集成的一种方案。Struts1.X与Spring集成——第一种方案

此篇博客还以上篇博客的登录例子为例,介绍Struts1.X与Spring集成的另一种方案。

1,第一种方案 原理

回忆第一种方案集成原理:在Action中取得BeanFactory,通过BeanFactory取得业务逻辑对象

此种方案的缺点:从严格意义的分层上来看,Action上看到了Spring的相关东西,依赖Spring
API去查找东西,发生了依赖查找,因为要查找依赖对象,所以要依赖Spring服务才能找到,因为在Spring提供的工厂里。应该是Action中看不到Spring相关东西,Action中看到的就是业务接口,这样的话层次更加分明。

2,第二种方案 原理

基于第一种方案的缺点,我们改成不在去查找业务对象,让IOC注入进来,只要提供setter方法,就能把对象主动传过来——依赖注入(局限性:在同一个JVM里可以,跨JVM不可以依赖注入)

如果想被Spring注入,Action需要被Spring管理,也就是说LoginAction的创建是从IOC容器中创建出来的,而不应该再是让Struts创建。如果还是Struts创建的话,UserManager是不可能注入进来的。只有从IOC容器中拿出来的东西,所有的依赖关系才被注入,所以Action必须被Spring管理,被Spring管理,就需要配置到Spring的配置文件中。

applicationContext-beans.xml:

applicationContext-action.xml:

只要通过BeanFactory getBean()把"LoginAction"拿到,同时userManager的依赖关系都会注入进去;

3,分析第二种方案提出的原由

第一种方案:

Web客户端发出请求,请求ActionServlet,Struts流程是在Struts里面要查看Struts-config.xml,把LoginAction拿出来new,如下:

Struts进行new,只会new LoginAction,其他的UserManager不会new,也不会注入。

所以此种流程是不行的,依赖对象不能注入。

但是,用Struts的话必须得请求Action,所以需要使用Spring,Spring实现了一个Action(Action代理类:ActionProxy)——不会改变原先Action的相关接口,只是代理,代理可以控制原目标,在调目标之前可以做些事情。所以Struts-config.xml文件中就不应该配置LoginAction.java这个类了,要配置Spring给提供的一个类,它提供的类起到了什么作用:web客户端发出请求,需要Struts把Spring提供的代理类new出,这个代理类中负责拿到BeanFactory,通过getBean(),把这次请求对应的Action拿出来(是从IOC容器中拿出LoginAction),那么它的依赖对象就都会被注入。如下图第二种方案:

第二种方案:

将第一种方案,Struts-config.xml中配置的LoginAction.Java类(如下图(1))改为配置org.springframework.web.struts.DelegatingActionProxy.class(2)

(1)

(2)

(3)

applicationContext-action.xml:配置LoginAction类,来管理LoginAction类

一个请求过来,Struts中new出代理类DelegatingActionProxy,通过代理类调用getBean(beanName,Action.Class)方法,将path的名称"/login"传入,到IOC中找到对应name的Action(即,LoginAction类(在applicationContext-action.xml中配置过了,如图(3)))

第二种方案集成原理:Struts的Action交给Spring创建;

将业务逻辑对象通过spring注入到Action中,从而避免了在Action类中的直接代码查询

(客户端请求---->代理action--->取得BeanFactory--->getBean(..)创建action示例--->执行exctute方法)

4,代码示例

简单登录例子

只是Spring配置文件和Struts配置文件,以及LoginAction.java有所变动,其他代码参考Struts1.X与Spring集成——第一种方案

struts-config.xml配置文件:配置代理Action及ActionForm

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">

<struts-config>
<!--生命ActionForm(即,告诉Struts哪个是ActionForm)  -->
    <form-beans>
       <form-bean name="loginForm" type="com.bjpowernode.usermgr.web.forms.loginActionForm"/>
    </form-beans>

<!-- 描述Action -->
   <!-- 描述Action -->
    <action-mappings>
        <action path="/login"
                type="org.springframework.web.struts.DelegatingActionProxy"
                name="loginForm"
                scope="request">   

        <!-- 转向信息 -->
        <forward name="success" path="/login_success.jsp"/>
        </action>
    </action-mappings>
    <message-resources parameter="MessageResources" />
</struts-config>

applicationContext-beans.xml配置文件:配置业务逻辑对象

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	     xmlns:aop="http://www.springframework.org/schema/aop"
	     xmlns:tx="http://www.springframework.org/schema/tx"
	     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
	<!-- 这个IOC容器核心是个工厂,抽象工厂 -->
	<bean id="userManager" class="com.bjpowernode.usermgr.manager.UserMangerImpl"/>

</beans>

applicationContext-action.xml配置文件:配置Struts的Action

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	     xmlns:aop="http://www.springframework.org/schema/aop"
	     xmlns:tx="http://www.springframework.org/schema/tx"
	     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
	<!-- 配置Struts的Action -->
	<bean name="/login" class="com.bjpowernode.usermgr.web.actions.LoginAction" scope="prototype">
       <property name="userManager" ref="userManager"/>
   </bean>
</beans>

5,运行

参考Struts1.X与Spring集成——第一种方案

6,总结

第一种方案原理:在Action中取得BeanFactory,通过BeanFactory取得业务逻辑对象——依赖查找;

第二种方案原理:将Struts的Action交给Spring创建,这样业务逻辑对象将会被注入——依赖注入;

两者区别及优缺点:

第一种是依赖查找,因为要查找依赖对象,所以要依赖Spring服务才能找到,这样就依赖了Spring服务,如果脱离了Spring,Action对象不能单独使用。

第二种是依赖注入,不依赖于别的服务,这样就避免了依赖查找,不用关系其他服务是如何工作的,没有侵入性,从而也使代码很清晰。

Struts1.X与Spring集成——第二种方案

时间: 2024-11-10 01:00:57

Struts1.X与Spring集成——第二种方案的相关文章

Struts1.X与Spring集成——第一种方案

spring+struts(第一种方案) 集成原理:在Action中取得BeanFactory,通过BeanFactory取得业务逻辑对象,调用业务逻辑方法. 一,新建一个项目Spring_Struts_01 二,步骤 1.spring和Struts的依赖包配置 *Struts (1)拷贝Struts和jstl的依赖包 (2)在web.xml文件中配置ActionServlet <span style="font-family:KaiTi_GB2312;font-size:18px;&qu

Spring+Struts集成(第二种方案)

在上一篇文章中我们了解到了第一种Spring跟Struts集成的方案,但此集成方案的不足是WEB层中知道Spring的相关内容,因为需要去主动的查找对象:BeanFactory.方案二便是通过依赖注入的方式来进行.通过Spring提供ActionProxy进行代理.去获取BeanFactory,找到Path的名称,然后找到path路径下的Action,然后完成注入. 方案二的核心:Struts的核心交给Spring来创建.Spring跟其他框架集合主要也是通过此种方式. 方案二集成框架图: sp

关于整合spring+mybatis 第二种方式

和第一种方式一样的步骤,不过bean.xml中有些许差异 <!-- 配置sqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property&g

ActiveMQ(06):ActiveMQ结合Spring开发--第二种方式

一.pom.xml与mq.properties Spring提供了对JMS的支持,需要添加Spring支持jms的包,如下: <dependency>     <groupId>org.springframework</groupId>     <artifactId>spring-jms</artifactId>     <version>4.1.7.RELEASE</version> </dependency&g

自定义tabBar详解第二种方案

自定义tabBar能够解决自定义图片无法显示(只显示一块颜色)这个弊端,自定义tabBar要继承UITabBarController 原图片: (1),  (2), (3),  (4), (5) 下面是自定义了一个TabBar ,每个按钮可以显示图片(自定义避免了图片无法显示只显示一块颜色) 效果图: 代码实现: 一, 首先创建一个继承UIButton的类CustomTabBar, 在.h文件中: //指定协议是为了实现点击button显示相应地页面,像系统的tabBar一样 @protocol

HBase存储时间相关多列数据的两种方案

所谓“时间相关多列数据”指的是同一个Key下具有多个属性数据,并且这些数据与时间具有相关性,多数场景是该Key对应在不同时间时刻的行为数据.在实际应用中,这类数据很多,例如电子商务网站上用户最近一段时间浏览的宝贝集合.访问的URL列表等. 使用HBase存储此类数据时,有以下两种常用的方案: 多行单列 表结构设计 Row Key:用户标识ID + (Long.MAX_VALUE - timestamp) Column Family:’cf’ Column Qualifier:’’ Value:宝

[java代码库]-简易计算器(第二种)

第二种方案:在程序中不使用if/switch……case等语句,完成计算器功能. <html> <head> <title>简易计算器</title> <script language="javascript">//易错:不是"text/javascript" function doCal(){ var value1=parseInt(document.getElementById("value1

【Win 10 应用开发】文件读写的三种方案

本文老周就跟伙伴们探讨一下关于文件读写的方法.总得来说嘛,有三种方案可以用,而且每种方案都各有特色,也说不上哪种较好.反正你得记住老祖宗留给我们的大智慧——事无定法,灵活运用者为上. OK,咱们开始吧. 先说第一个方案:使用 FileIO类. 这个类属于RT库API,它公开了一堆静态方法,可以直接调用,快捷方便,就像.net里面的File类一样.在使用FileIo类的时候,需要一个引用已知文件的StorageFile实例,而且FileIo只能操作已经存在的文件,它不会自动创建文件,这一点要注意.

Linux下实现秒级定时任务的两种方案(crontab 每秒运行)

第一种方案,当然是写一个后台运行的脚本一直循环,然后每次循环sleep一段时间. while true ;do command sleep XX //间隔秒数 done 第二种方案,使用crontab. 我们都知道crontab的粒度最小是到分钟,但是我们还是可以通过变通的方法做到隔多少秒运行一次. 以下方法将每20秒执行一次 crontab -e * * * * * /bin/date * * * * * sleep 20; /bin/date * * * * * sleep 40; /bin