struts和spring整合首先要在Web容器启动的时候自动装配ApplicationContext的配置信息,可想而知应该在web.xml做相应的配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
配置了org.springframework.web.context.ContextLoaderListener后我们就不惜要编写代码显示地实例化ApplicationContext对象了。至于为什么要使用监听是因为
web.xml 的加载顺序是:
context-param -> listener -> filter -> servlet
。如果你是在不想使用监听,或许你可以尝试下继承struts2的org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter重写这个它的init方法![大笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
1、使用xml方式:
struts2配置
<package name="user" extends="struts-default">
<action name="login" class="userAction">
<result name="success">/success.jsp</result>
<result name="input" type="redirect">/index.jsp</result>
</action>
</package>
spring配置
<bean id="userDao" class="org.han.dao.impl.UserDaoImpl" />
<bean id="biz" class="org.han.service.impl.LoginBizImpl">
<property name="userdao" ref="userDao"/>
</bean>
<bean id="userAction" class="org.han.action.LoginAction" scope="prototype" >
<property name="biz" ref="biz" />
</bean>
注意红色部分,struts2的action class与对应的action bean必须相同,这样才能由spring管理action;
2、struts2使用零配置方式:
当你导入了零配置插件包的时候千万要注意约定大于配置,还是上面的spring配置,只是不需要struts2配置了。
第一种方式:只需要将Action的className对应到spring配置中的bean id就行了
@Action(value = "/login", results = { @Result(name = "success", location = "/success.jsp"),@Result(name="input",location="/index.jsp")},className="userAction")
public String login() throws Exception {
// TODO Auto-generated method stub
User u=biz.login(this.getUser());
if(u!=null){
return SUCCESS;
}
return INPUT;
}
第二种方式:
Action注解不需要className了,将spring配置稍作修改
<bean id="org.han.action.LoginAction" class="org.han.action.LoginAction" scope="prototype" >
<property name="biz" ref="biz" />
</bean>
这样可以是因为当你使用零配置的时候,action的class默认是当前类的全类名,所以和spring整合的时候刚好使用全类名在spring配置中查找以全类名为id的bean。
3、struts2、spring都使用注解方式:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="org.han.dao.impl,org.han.service.impl,org.han.action"/>
</beans>
@Namespace("/")
@Component(value="userLogin")
@Scope(value="prototype")
public class LoginAction extends ActionSupport {
public LoginAction() {
super();
// TODO Auto-generated constructor stub
System.out.println("action:"+this.hashCode());
}
@Autowired
private ILoginBiz biz;
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Autowired
public void setBiz(ILoginBiz biz) {
this.biz = biz;
}
@Override
@Action(value = "hello", results = { @Result(name = "success", location = "/success.jsp"),@Result(name="input",location="/index.jsp")})
public String execute() throws Exception {
// TODO Auto-generated method stub
System.out.println("biz:"+this.biz.hashCode());
User u=biz.login(this.getUser());
if(u!=null){
return SUCCESS;
}
return INPUT;
}
}
@Component 有一个可选的入参,用于指定 Bean 的名称。一般情况下,Bean 都是 singleton 的,需要注入 Bean 的地方仅需要通过 byType 策略就可以自动注入了,所以大可不必指定 Bean 的名称。除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。虽然目前这 3 个注释和 @Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释。
3、注释配置往往是类级别的,而 XML 配置则可以表现得更加灵活。比如相比于 @Transaction 事务注释,使用 aop/tx 命名空间的事务配置更加灵活和简单。
所以在实现应用中,我们往往需要同时使用注释配置和 XML 配置,对于类级别且不会发生变动的配置可以优先考虑注释配置;而对于那些第三方类以及容易发生调整的配置则应优先考虑使用 XML 配置。Spring 会在具体实施 Bean 创建和 Bean 注入之前将这两种配置方式的元信息融合在一起。