zoukankan      html  css  js  c++  java
  • 8 -- 深入使用Spring -- 7...3 让Spring管理控制器

          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-INFlib目录下。

            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的业务逻辑组件接收容器注入,将导致代码的可读性降低。

    啦啦啦

    啦啦啦

    啦啦啦

  • 相关阅读:
    《分析服务从入门到精通读书笔记》第四章、维度部署浏览篇(3)
    集群(cluster)原理(转)
    Atitit 前端测试最简化内嵌web服务器 php 与node.js 目录 1.1. php内置Web Server 1 1.2. Node的 2 Node的比较麻烦些。。Php更加简单
    Atitit mybatis使用简明教程 目录 1.1. Mybatis.xml 配置文件 1 1.2. Datamp.xml mapper文件主要作用是分模块放sql语句 2 1.3. 查询
    Atitit 业务流程执行引擎的实现 目录 1.1. 引擎实现语言java js php等 1 1.2. 流程语言 xml sql js等 业务流程定义语言规范总结 1 1.3. 实体方法定义 2
    Atitit 常见软件设计图纸总结 目录 1.1. ui原型图与html 2 1.2. 业务逻辑 伪代码 各种uml图 2 1.3. 总体设计图纸 结构图 层次图 架构图 2 1.4. 业务逻辑
    Atitit velocity 模板引擎使用法 目录 1.1. 1.4 Context 1 1.1.1. 1.4.1 Context 基本概念 1 1.2. .3不同模式下使用velocity 1
    Atitit mysql存储过程编写指南 1. 定义变量 1 1.1. 变量名以@开头用户变量 会话变量 1 1.2. 以declare关键字声明 存储过程变量 2 1.3. @是用户自定义变量,
    Atitit 算法的艺术 attilax艾提拉著v7 t88.docx Atitit 算法之道 attilax著 1. 文本方面的编码算法 3 1.1. Base64 htmlencode url
    Atitt 常见的拖欠费用的公司与个人黑名单 陕西西部安全网 20072008 西安 一个月 25000 西安盛世涅槃 2007 西安 1m 25000 Sicyi msc 2007 n
  • 原文地址:https://www.cnblogs.com/ClassNotFoundException/p/6661637.html
Copyright © 2011-2022 走看看