2015年07月17日 16:00:36
阅读数:4320
当我们在一个ACTION类里面写很多个方法的时候(其实是一种按功能划分模块编程的思想),每个方法的返回状态可能不一样,如果ACTION中不@Scope("prototype"),有可能报找不到XXXACTION的错误!写上这个就表示每次请求都重新创建一个ACTION,与SINGALON对应,俗称“多例”。
singleton:SpringIoc容器只会创建该Bean的唯一实例,所有的请求和引用都只使用这个实例
Property: 每次请求都创建一个实例
request: 在一次Http请求中,容器会返回该Bean的同一个实例,而对于不同的用户请求,会返回不同的实例。需要注意的是,该作用域仅在基于Web的Spring ApplicationContext情形下有效,以下的session和global Session也是如此
session:同上,唯一的区别是请求的作用域变为了session
global session:全局的HttpSession中,容器会返回该bean的同一个实例,典型为在是使用portlet context的时候有效(这个概念本人也不懂)
注意:如果要用到request,session,global session时需要配置
servlet2.4及以上:
在web.xml中添加:
<listener>
<listener-class>org.springframework.web.context.scope.RequestContextListener />
</listener>
servlet2.4以下:
需要配置一个过滤器
<filter>
<filter-name>XXXX</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
<filter-mapping>
<filter-name>XXXX</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
另外,从2.0开始,可以自己定义作用域,但需要实现scope,并重写get和remove方法
特别要引起注意的是:
一般情况下前面两种作用域是够用的,但如果有这样一种情况:singleton类型的bean引用一个prototype的bean时会出现问题,因为singleton只初始化一次,但prototype每请求一次都会有一个新的对象,但prototype类型的bean是singleton类型bean的一个属性,理所当然不可能有新prototpye的bean产生,与我们的要求不符
解决方法:
1.放弃Ioc,这与设计初衷不符,并代码间会有耦合
2,Lookup方法注入,推荐
但在用Lookup方法注入时也需要注意一点:需要在引用的Bean中定一个一个抽象地返回被引用对象的方法
package com.huyong.lookup;
import java.util.Calendar;
/**
* @author
*/
public class CurrentTime {
private Calendar now = Calendar.getInstance();
public void printCurrentTime() {
System.out.println("Current Time:" + now.getTime());
}
此取值时表明容器中创建时只存在一个实例,所有引用此bean都是单一实例。如同每个国家都有一个总统,国家的所有人共用此总统,而这个国家就是一个spring容器,总统就是spring创建的类的bean,国家中的人就是其它调用者,总统是一个表明其在spring中的scope为singleton,也就是单例模型。
此外,singleton类型的bean定义从容器启动到第一次被请求而实例化开始,只要容器不销毁或退出,该类型的bean的单一实例就会一直存活,典型单例模式,如同servlet在web容器中的生命周期。
spring容器在进行输出prototype的bean对象时,会每次都重新生成一个新的对象给请求方,虽然这种类型的对象的实例化以及属性设置等工作都是由容器负责的,但是只要准备完毕,并且对象实例返回给请求方之后,容器就不在拥有当前对象的引用,请求方需要自己负责当前对象后继生命周期的管理工作,包括该对象的销毁。也就是说,容器每次返回请求方该对象的一个新的实例之后,就由这个对象“自生自灭”,最典型的体现就是spring与struts2进行整合时,要把action的scope改为prototype。
如同分苹果,将苹果的bean的scope属性声明为prototype,在每个人领取苹果的时候,我们都是发一个新的苹果给他,发完之后,别人爱怎么吃就怎么吃,爱什么时候吃什么时候吃,但是注意吃完要把苹果核扔到垃圾箱!对于那些不能共享使用的对象类型,应该将其定义的scope设为prototype。
Spring在Action上面注解@Scope("prototype")
表示每次接收一个请求创建一个Action对象..
如若改成其他,例如单例模式,则很多请求公用同一个Action.
一个注册的例子,如果没加上这个注解,注册完成后,下一个请求再注册一次,Action里会保留上一次注册的信息..