一、由struts2 框架自身根据struts.xml 中 的映射实例化Action 对象html
Action 类代码以下:java
package com.hasonger.ssh.action; import java.util.Date; import com.hasonger.ssh.entity.User; import com.hasonger.ssh.service.UserService; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; public class UserAction extends ActionSupport implements ModelDriven<User> { private static final long serialVersionUID = 1L; private User user; private UserService userService; public UserAction(){ System.out.println("UserAction construstor........"); } public void setUserService(UserService userService) { this.userService = userService; } public String register() { user.setRegTime(new Date()); userService.save(user); return SUCCESS; } @Override public User getModel() { return user = new User(); } }
struts.xml 文件配置以下:web
<package name="default" namespace="/" extends="struts-default"> <action name="user_register" class="com.hasonger.ssh.action.UserAction" method="register"> <result>/jsp/success.jsp</result> </action> </package>
在表单页面填写注册信息后,控制台输出以下:spring
信息: Starting ProtocolHandler ["ajp-apr-8009"] 七月 10, 2014 4:32:31 下午 org.apache.catalina.startup.Catalina start 信息: Server startup in 13551 ms UserAction construstor........ Hibernate: insert into ssh.user (USERNAME, PASSWORD, REG_TIME) values (?, ?, ?) UserAction construstor........ Hibernate: insert into ssh.user (USERNAME, PASSWORD, REG_TIME) values (?, ?, ?)
通过实际测试,并结合struts文档能够看出,在WEB 应用容器启动过程当中Action 不会实例化,在客户发出action 请求后 由struts 框架实例化Action 对象,而且Action 默认是多实例的,即每发出一次action 请求,struts 都会产生一个新的Action 对象。sql
从UserAction 类的整个代码看,UserAction 类没有交给IoC容器管理,而且userService 属性也没有显式的装配,struts2文档中提到像这种状况,由struts 框架产生Acition 实例,并结合Spring IoC 容器自动装配依赖的属性。固然这须要给依赖的属性提供setter 方法才能够完成。apache
可是若把struts.xml 文件改为以下配置:服务器
<package name="default" namespace="/" extends="struts-default"> <action name="user_register" class="userAction" method="register"> <result>/jsp/success.jsp</result> </action> </package>
再次发起action 请求时会产生错误:错误信息提示不能实例化userAction.app
二、由Spring IoC 容器产生Action 实例,并负责管理Action 对象的生命周期:框架
Action 类代码以下:ssh
package com.hasonger.ssh.action; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import com.hasonger.ssh.entity.User; import com.hasonger.ssh.service.UserService; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; @Controller public class UserAction extends ActionSupport implements ModelDriven<User> { private static final long serialVersionUID = 1L; private User user; private UserService userService; public UserAction(){ System.out.println("UserAction construstor........"); } @Autowired public void setUserService(UserService userService) { this.userService = userService; } public String register() { user.setRegTime(new Date()); userService.save(user); return SUCCESS; } @Override public User getModel() { return user = new User(); } }
struts.xml 配置以下:
<package name="default" namespace="/" extends="struts-default"> <action name="user_register" class="com.hasonger.ssh.action.UserAction" method="register"> <result>/jsp/success.jsp</result> </action> </package>
应用程序部署在WEB 容器后,启动WEB 容器控制台输出以下:
七月 10, 2014 5:16:23 下午 org.apache.catalina.core.ApplicationContext log 信息: No Spring WebApplicationInitializer types detected on classpath 七月 10, 2014 5:16:23 下午 org.apache.catalina.core.ApplicationContext log 信息: Initializing Spring root WebApplicationContext log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. UserAction construstor........ 七月 10, 2014 5:16:28 下午 org.apache.coyote.AbstractProtocol start 信息: Starting ProtocolHandler ["http-apr-8080"] 七月 10, 2014 5:16:28 下午 org.apache.coyote.AbstractProtocol start 信息: Starting ProtocolHandler ["ajp-apr-8009"] 七月 10, 2014 5:16:28 下午 org.apache.catalina.startup.Catalina start 信息: Server startup in 14104 ms
从控制台输出的信息能够看出,Action 对象交给IoC 容器管理后,在服务器启动过程当中IoC 容器初始化的同时也实例化了Action 对象。因此默认状况下,Action 的做用域是singleton 类型的。
屡次发起action 请求继续测试:IoC 容器不会再次产生Action 类的实例了
若将UserAction 的做用域手动改成singleton 类型的,再次连续发起action 请求,控制台仍是会显示上面的信息。
若将struts.xml 文件配置改成以下:即将<action> 节点的class 属性改成Action 类在IoC 容器中bean的name 属性值
<package name="default" namespace="/" extends="struts-default"> <action name="user_register" class="userAction" method="register"> <result>/jsp/success.jsp</result> </action> </package>
部署应用后启动服务器过程当中,控制台的输出信息以下:
信息: Initializing Spring root WebApplicationContext log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. UserAction construstor........ 七月 10, 2014 5:43:26 下午 org.apache.coyote.AbstractProtocol start 信息: Starting ProtocolHandler ["http-apr-8080"] 七月 10, 2014 5:43:26 下午 org.apache.coyote.AbstractProtocol start 信息: Starting ProtocolHandler ["ajp-apr-8009"] 七月 10, 2014 5:43:26 下午 org.apache.catalina.startup.Catalina start 信息: Server startup in 13848 ms
从控制台输出的信息能够看出: 在IoC 容器管理Action 对象后,<action> 节点的class 属性值无论是Action 的全类名仍是bean 的name 属性值, IoC 容器都会实例化Action 对象。
当发起多个action 请求后控制台输出以下(<action> 节点的class 属性值为userAction):
信息: Initializing Spring root WebApplicationContext log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. UserAction construstor........ 七月 10, 2014 5:43:26 下午 org.apache.coyote.AbstractProtocol start 信息: Starting ProtocolHandler ["http-apr-8080"] 七月 10, 2014 5:43:26 下午 org.apache.coyote.AbstractProtocol start 信息: Starting ProtocolHandler ["ajp-apr-8009"] 七月 10, 2014 5:43:26 下午 org.apache.catalina.startup.Catalina start 信息: Server startup in 13848 ms Hibernate: insert into ssh.user (USERNAME, PASSWORD, REG_TIME) values (?, ?, ?) Hibernate: insert into ssh.user (USERNAME, PASSWORD, REG_TIME) values (?, ?, ?) Hibernate: insert into ssh.user (USERNAME, PASSWORD, REG_TIME) values (?, ?, ?)
控制台的信息显示:Action 对象的做用域是singleton 类型的。
保持<action> 节点的class 属性值为userAction,继续测试,在UserAction 的做用域设置为prototype 类型后,启动服务器过程当中没有Action 类 被实例化,而是每次发起action 请求时才会实例化Action 对象。代码以下:
package com.hasonger.ssh.action; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import com.hasonger.ssh.entity.User; import com.hasonger.ssh.service.UserService; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; @Controller @Scope("prototype") public class UserAction extends ActionSupport implements ModelDriven<User> { private static final long serialVersionUID = 1L; private User user; private UserService userService; public UserAction(){ System.out.println("UserAction construstor........"); } @Autowired public void setUserService(UserService userService) { this.userService = userService; } public String register() { user.setRegTime(new Date()); userService.save(user); return SUCCESS; } @Override public User getModel() { return user = new User(); } }
若将UserAction 的userService 属性setter 方法的@Autowired 注解去除,继续测试,发起action 请求一切正常,这说明Action 类 依赖属性不手动添加@Autowired 注解 也能够被注入。
经过实际测试实验总结以下:
struts2.3.16整合spring4.0.五、hibernate4.3.0 时,Action 类实例的产生和做用域状况:
一、由struts2 框架自身根据struts.xml 中 的映射实例化Action 对象:
①Action 类的依赖属性由struts2框架自动装配,不须要手动写@Autowired 注解;
②Action 类为多实例的;
③在struts.xml 配置中<action> 字节点的class 属性值只能是Action 类的全类名;
二、由Spring IoC 容器产生Action 实例,并负责管理Action 对象的生命周期:
①默认状况下Action 实例的scope 属性值为singleton;
②在WEB 环境下必须将Action 类scope 属性值设置为prototype 类型的;
③在struts.xml 配置中 <action> 字节点的class 属性值有两种选择:一种是Action 类的全类名,另外一种是Action 类在 Spring IoC 容器中bean的 name 属性值;
④Action 类的依赖属性(如:业务层的对象)既能够由struts 框架自动的装配——不须要在依赖属性的setter 方法上加@Autowired 注解,也能够手工的加上@Autowired 注解,加上后不出错。
⑤上述全部自动装配依赖属性均须要提供相应的setter 方法,不然装配不上。