[SSH]struts2-spring-plugin.jar这个包的作用

时间:2022-02-27 04:37:32

本文转自:http://blog.sina.cn/dpool/blog/s/blog_4a878d2a0100r81y.html?vt=4

    在我们集成struts2+spring+hibernate,也就是所谓的S2SH,不可避免的要引入struts2-spring-plugin.jar插件。
    当引入这个插件后,原先所struts创建的action类,交给了spring创建。
    在struts2-spring-plugin.jar中有一个struts-plugin.xml,里面声明了action类由spring工厂创建。在struts2插件文档里,这样写着“The Spring Plugin works by overriding the Struts ObjectFactory to enhance the creation of core framework objects。”
    这个插件重写了struts的对象工厂,当创建一个action类时,它会根据struts的配置文件的class属性的值与spring配置文件中的id属性的值相匹配。如果没有与之相匹配,将会像没有使用这个插件前一样创建,然后由spring自动装配。
    那时我有些不是很明白,为什么我的action类没有写注解@Component(‘xxAction’),还是可以被spring自动装配。那是因为action类被struts和struts2-spring-plugin创建,再由spring自动装配,但不由spring管理。如果我们想使用spring复杂的aop或spring其他的功能时,强烈建议将acion类注册到spring容器中。即让spring去创建action类。
    今天,再次做测试,又有了出乎意料的结果。在此说明,我的测试中用的是annotion注解,不是xml文件。
    之前,我们说过,当创建一个action类时,它会根据struts的配置文件的class属性的值与spring配置文件中的id属性的值相匹配。如果没有与之相匹配,将会像没有使用这个插件前一样创建,然后由spring自动装配。这两种情况会出现不同的结果。现在我们慢慢来说明。
    假设我们有一个AddUserAction的类,位于com.action包下,它有属性userService:

package com.action;
import com .opensymphony.xwork2.ActionSupport;
import com.service.UserService;
public class AddUserAction extends ActionSupport {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public String execute() throws Exception {
System.out.println(userService==null);
return SUCCESS;
}
}

    以上这个类是我们最简单的action类,在没有引入struts2-spring-plugin.jar插件时,action类是由struts创建的,我们struts.xml文件是这样写的:

<struts>
<package name='registration' extends='struts-default'>
<action name='addUser' class='com.action.AddUserAction'>
<result>success.jsp</result>
</action>
</package>
</struts>

    但如果我们引入struts2-spring-plugin.jar插件后,如果我们的struts.xml文件还是如同以上一样写,就会出现struts的配置文件的class属性的值与spring配置文件中的id属性的值不匹配,因为action类没有注册到spring的容器中。
    那action的创建由strutst和struts2-spring-plugin.jar插件创建,默认地根据名字到spring容器中去找相应的对象进行自动装配(不管你是否愿意,只要提供了set方法),所以userService不会是null值,这个action类的scope也默认的是prototype,但这个action类不在spring容器中。
    自然的,以上这种情况不是我们想要的,因为很多情况都不在我们的控制范围内。那只要我们将action类的创建交给spring,就可以自主也配置我们想要的属性。这时我们将原来的action类改为:

package com.action;
mport javax.annotation.Resource;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.opensymphony.xwork2.ActionSupport;
import com.service.UserService;
@Component('addUserAction')
@Scope('prototype')
public class AddUserAction extends ActionSupport {
private UserService userService;
@Resource(name='userService')
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public String execute() throws Exception {
System.out.println(userService==null);
return SUCCESS;
}
}

    在第二个action类中,我们加入了相应的annotion,把我们的action类注册到spring容器中。我们的struts.xml文件也改为:

<struts>
<package name='registration' extends='struts-default'>
<action name='addUser' class='addUserAction'>
<result>success.jsp</result>
</action>
</package>
</struts>

    这时,struts的配置文件的class属性的值与spring配置文件中的id属性的值匹配。如果我们不想装配userService(通过spring),可以将@Resource(name=’userService’)删除。
    所以,在struts.xml里的class的属性值决定你以那种方式创建action类,我个人倾向于将action类交给spring管理和自动装配。