Struts2整合Spring之一:双方的分工


   引入一个Struts整合Spring的简单例子,来说明两者的分工。

   分工总体来讲:struts仍然通过Action来接收jsp传来的数据,处理后进行跳转;spring仍然只负责把具体实例注入。但spring这次要在合适的时候,把service实例注入struts管理的Action之中,struts要通过配置 允许spring来管理整个实例化的过程。

   所以struts是主导、是管理者,只有struts需要某个实例的时候,才会管spring去请求被注入,spring只是配合注入所需实例


    

    

    具体的变化:

    1.引入struts2-spring-plugin,使得struts能够管spring去要实例

    2.web.xml :加入spring的Listener、加入spring配置文件(applicationContext-common.xml)的地址

    3.applicationContext-common.xml :要把service注入到struts管理的Action里(原来都是注入到DAO里)

    4.具体的Action :聚合一个Iservice对象,留有setter接口 ,等待spring注入之 



1.web.xml

我是用struts的例子里边加的spring的配置,

除了原有的struts过滤器,还要加入spring的监听器,让spring在适当的时候能注入

  <!-- 应用中Struts的过滤器 -->
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

	<!-- 配置让框架尝试使用spring创建对象 -->
	<listener> 
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
	</listener>
	<!-- 指定spring主配置文件 --> 
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value>
	</context-param>

struts2-spring-plugin文档(http://struts.apache.org/2.x/docs/spring-plugin.html)中提到的加入监听器的目的:

By default, the framework will at least try to use Spring to create all its objects. If the object cannot be created by Spring, then the framework will create the object itself.
Enabling Spring integration for other application objects is a two-step process.
第二步在下边:



2.applicationContext-common.xml

顺着文档的介绍顺序说:

加入前边的监听器以后,就能把spring的配置文件里边配置的实例注入到目的实例中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

  <!-- 实现 -->
  <bean id="loginService" class="com.rt.struts2.service.LoginServiceImpl"></bean>  
  <!-- 注入实现, 原来是往DAO里注入,现在注入struts管辖的action-->
  <!-- scope应该为多例,单例会互相干扰-->
  <bean id="loginAction" class="com.rt.struts2.actionDemo.LoginAction" scope="prototype">  
    <property name="loginService" ref="loginService"></property>  
  </bean> 

</beans>
之前都是用spring把service实例注入到DAO里,这次要 注入到struts管理的Action里了


3.Action

具体的Action之前由struts全权负责:tomcat访问Action时,struts去检查去生成

现在具体Action中多聚合了一个service实例,配置struts2-spring-plugin后,

tomcat再访问action时struts会检查到spring能帮我生成这个实例,所以交给spring去注入(所以要符合spring注入的规则)

package com.rt.struts2.actionDemo;

import com.opensymphony.xwork2.ActionSupport;  
import com.rt.struts2.service.ILoginService;

public class LoginAction extends ActionSupport 
{  
    private ILoginService loginService;  //聚合service
    private String userName;  
    private String password;  
    
    public void setLoginService(ILoginService loginService) {  //spring从这个函数注入
        this.loginService = loginService;  
    }  
    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;  
    }  
    @Override  
    public String execute() throws Exception {  
        if(loginService.isLogin(userName, password))  
            return SUCCESS;  
        else  
            return INPUT;  
    }  
}  



其余东西都不变:

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

<!--  实测加入struts-spring-plugin后可以去掉
    <constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
-->  
    <!-- Add packages here -->
    <constant name="struts.devMode" value="true" /><!-- 开发模式:修改后不用重启容器就能生效 -->
    <constant name="struts.i18n.encoding" value="GBK"/><!-- 中文防止乱码 -->


	<package name="Login" namespace="/" extends="struts-default">

		<action name="Login" class="com.rt.struts2.actionDemo.LoginAction">
			<result name="success">/result.jsp</result>
			<result name="input">/login.jsp</result>
		</action>
	</package>
     
</struts>

LoginServiceImpl.java

package com.rt.struts2.service;

public class LoginServiceImpl implements ILoginService {  
	  
    public boolean isLogin(String userName, String password) {  
        if("name".equals(userName) && "pwd".equals(password))  
            return true;  
        else   
            return false;  
    }  
} 


ILoginService.java

package com.rt.struts2.service;

public interface ILoginService 
{
	boolean isLogin(String userName,String password);  
}

还有俩jsp页面,一个负责提交一个表单,一个随便有些显示就行了





===============================================================================================

补充个整合过程中遇到的小问题:

Exception sending context destroyed event to listener instance of class org.springframework.web.context.ContextLoaderListener


解决方法是:把下面的内容配置到web.xml中

<!-- 用来定位Spring XML文件的上下文配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value>
</context-param>

文档中的言辞让人感觉这个配置不是必需的,可是不加还真不行。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值