8.7.3 让Spring管理控制器

        让Spring容器来管理应用中的控制器,可以充分利用Spring的IoC特性,但需要将配置Struts 2 的控制器部署在Spring容器中,因此导致配置文件冗余。

        Struts 2 的核心控制器首先拦截到用户请求,然后将请求转发给对应的Action处理,在此过程中,Struts 2 将负责创建Action实例,并调用其execute()方法。这个过程是固定的(除非改写Struts 2 的核心控制器)。现在的情形是:如果把Action实例交由Spring容器来管理,而不是由Struts 2 产生的,那么核心控制器如何知道调用Spring容器中的Action,而不是自行创建Action实例呢?

        进入Struts 2 项目的lib目录下,可以找到一个struts2-spring-plugin-x.x.x.x.jar文件,这个JAR包就是Struts 2 整合Spring 的插件,简称Spring插件。为了将Struts 2、Spring进行整合开发,首先应该将JAR包复制Web应用的WEB-INF\lib目录下。

        Spring插件提供了一种为Action,在struts.xml文件中配置Action时,通常需要指定class属性,该属性就是用于创建Action实例的实现类。但Struts 2 提供的Spring 插件允许指定class 属性时,不再指定Action的实际实现类,而是指定为Spring 容器中的Bean ID,这样Struts 2 不在自己负责创建Action实例,而是直接通过Spring容器去获取Action对象。

        通过上面的方式,不难发现这种整合策略的关键:当Struts 2 将请求转发给指定的Action时,Struts 2 中的该Action只是一个“傀儡”,它只是一个代号,并没有指定实际的实现类,当然也不可能创建Action实例,而隐藏在该Action下的是Spring容器中的Action实例 ------- 它才是真正处理用户请求的控制器。

        Struts 2 只是配置一个伪控制器,这个伪控制器的功能实际由Spring容器中的控制器来完成,这就实现了让核心控制器调用Spring 容器中的Action来处理用户请求。

        在这种整合策略下,处理用户请求的Action有Spring插件负责创建,但Spring插件创建Action实例时,并不是利用配置Action时指定的class 属性来创建Action实例,而是从Spring容器中取出对应的Bean实例完成创建的。

        登录页面:--------------------------------------------------

        为了处理用户请求,必须提供处理用户请求的Action类,该Action需要调用业务逻辑组件的业务逻辑方法来处理用户请求。在实际的Java EE项目中,Action只是系统的控制器,也不应该处理用户请求,处理用户请求是业务逻辑实现,理应有业务逻辑组件来提供实现。

        Class : LoginAction

package edu.pri.lime.account.act;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport{ /**
*
*/
private static final long serialVersionUID = 1L; // 封装用户请求参数的两个成员变量
private String username;
private String password; // 系统所用的业务逻辑组件
private MyService ms;
// 设置注入业务逻辑组件所必需的setter方法
public void setMs(MyService ms){
this.ms = ms;
}
// 处理用户请求的execute方法
public String execute() throws Exception{
// 调用业务逻辑组件的validLogin()方法
// 验证用户名和密码
if(ms.validLogin(getUsername(),getPassword()) > 0){
addActionMessage("Congratulation!,Integer Succeed !");
return Action.SUCCESS;
}
return Action.ERROR;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
} }

        提示:

          Spring 容器为控制器注入业务逻辑组件,这也是Spring 和Struts 2 整合的关键所在。

        XML : Struts

<?xml version="1.0" encoding="UTF-8" ?>
<!-- 指定Struts 2 配置文件的DTD信息 -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd"> <!-- Struts 2 配置文件的根元素 -->
<struts>
<!-- 配置了一系列常量 -->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<constant name="struts.devMode" value="true"/>
<constant name="struts.enable.DynamicMethodInvocation" value="false"/> <package name="lime" extends="struts-default">
<!-- 定义处理用户请求的Action,该Action的class属性不是实际处理类,而是Spring容器中的Bean实例的ID -->
<action name="login" class="loginAction">
<!-- 为两个逻辑视图配置页面 -->
<result name="error">/WEB-INF/content/error.jsp</result>
<result name="success">/WEB-INF/content/welcome.jsp</result>
</action>
<!-- 让用户直接访问该应用时列出所有的视图页面 -->
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>

          Class : Service

package edu.pri.lime.account.service.impl;

import edu.pri.lime.account.service.MyService;

public class MyServiceImpl implements MyService{

    public int validLogin(String username, String password) {
if(username.equals("lime") && password.equals("oracle")){
return 99;
}
return -1;
} }

        XML : Spring

<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 部署一个业务逻辑组件 -->
<bean id="myService" class="edu.pri.lime.account.service.impl.MyServiceImpl"/> <!-- 让Spring管理Action实例,并依赖注入业务逻辑组件 -->
<bean id="loginAction" class="edu.pri.lime.account.act.LoginAction" scope="protytype">
<property name="ms" ref="myService"/>
</bean> </beans>

        注意:

          当使用Spring容器管理Struts 2 的Action时,由于每个Action对应一次用户请求,且封装了该次请求的状态信息,所以不应该Action配置成单例模式,因此必须指定scope属性,该属性值可制定为portotype或request。

        这种策略充分利用了Spring 的IoC特性,是一种较为优秀的解耦策略。这种策略也有一些不足之处,归纳起来,主要有如下不足之处:

          ⊙ Spring管理Action,必须将所有的Action配置在Spring容器中,而struts.xml文件中还需要配置一个“伪Action”,从而导致配置文件臃肿、冗余。

          ⊙ Action的业务逻辑组件接收容器注入,将导致代码的可读性降低。

啦啦啦

啦啦啦

啦啦啦

8 -- 深入使用Spring -- 7...3 让Spring管理控制器的更多相关文章

  1. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

  2. spring boot(五):spring data jpa的使用

    在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spr ...

  3. spring boot(三):Spring Boot中Redis的使用

    spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...

  4. [Spring]支持注解的Spring调度器

    概述 如果想在Spring中使用任务调度功能,除了集成调度框架Quartz这种方式,也可以使用Spring自己的调度任务框架. 使用Spring的调度框架,优点是:支持注解(@Scheduler),可 ...

  5. Spring注入JPA+JPA事务管理

    本例实现的是Spring注入JPA 和 使用JPA事务管理.JPA是sun公司开发的一项新的规范标准.在本质上来说,JPA可以看作是Hibernate的一个子集:然而从功能上来说,Hibernate是 ...

  6. 使用 Spring Boot 快速构建 Spring 框架应用--转

    原文地址:https://www.ibm.com/developerworks/cn/java/j-lo-spring-boot/ Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2 ...

  7. 全面分析 Spring 的编程式事务管理及声明式事务管理

    开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...

  8. Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->Spring Framework中的spring web MVC模块

    spring framework中的spring web MVC模块 1.概述 spring web mvc是spring框架中的一个模块 spring web mvc实现了web的MVC架构模式,可 ...

  9. Spring学习1-初识Spring

    一.简介   1.Spring是一个开源的控制反转(Inversion of Control ,IoC)和面向切面(AOP)的容器框架.它的主要目得是简化企业开发.  2.为何要使用Spring?   ...

  10. Spring第12篇—— Spring对Hibernate的SessionFactory的集成功能

    由于Spring和Hibernate处于不同的层次,Spring关心的是业务逻辑之间的组合关系,Spring提供了对他们的强大的管理能力, 而Hibernate完成了OR的映射,使开发人员不用再去关心 ...

随机推荐

  1. Java学习笔记:具体解释传值和传引用

    传值和传引用 When you're passing primitives into a method ,you get a distinct copy of the primitive. When ...

  2. Android训练课程(Android Training) - 高效的显示图片

    高效的显示图片(Displaying BitmapsEfficiently) 了解如何使用通用的技术来处理和读取位图对象,让您的用户界面(UI)组件是可响应的,并避免超过你的应用程序内存限制的方式.如 ...

  3. Bootstrap小体验

    感觉很不错,给人一种清淅 明了的感觉

  4. Sword STL之map效率问题

    #include <iostream> #include <map> #include <vector> using namespace std; /* STL容器 ...

  5. SpannableString

    http://blog.csdn.net/fengkuanghun/article/details/7904284 背景介绍 在开发应用过程中经常会遇到显示一些不同的字体风格的信息犹如默认的LockS ...

  6. 如何以Java实现网页截图技术

    转自   http://blog.csdn.net/cping1982/article/details/5353049 今天看到某网友关于“如何以Java实现网页截图技术”的咨询帖,由于出现该咨询的地 ...

  7. 【WPF】WPF DataGrid List数据源 双向绑定通知机制之ObservableCollection使用以及MultiBinding 的应用

    以下代码实现了DataGrid的简单绑定List数据源 重点要提一下的是,绑定List数据源,但是不能直接用List.比如下面的代码,使用List<GridItem>只能实现数据修改的绑定 ...

  8. Java如何显示小时和分钟?

    在Java中,如何显示小时和分钟(当前时间)? 此示例演示如何使用Calender类的Calender.getInstance()来显示某个时刻的小时和分钟. package com.yiibai; ...

  9. Swing AWT一套新的图形界面系统

    Swing 是在AWT的基础上构建的一套新的图形界面系统,它提供了AWT 所能够提供的所有功能,并且用纯粹的Java代码对AWT 的功能进行了大幅度的扩充. 例如说并不是所有的操作系统都提供了对树形控 ...

  10. [深入理解Android卷一全文-第三章]深入理解init

    因为<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. ...