`
gaddma
  • 浏览: 17356 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring bean的四种常用作用域的测试

 
阅读更多

Spring的 bean有5种作用域分别是:singleton、prototype、request、session和globalSession

简单介绍:

spring 起初的版本只有singleton,也就是是否是单例模式。

作用域包括:
singleton
全局只有一个实例
prototype
每次调用产生一个新的实例
在web使用的时候还有三个作用域,但是必须在web.xml中注册一个RequestContextListener , 目的是为了设置每次请求开始和结束都可以使spring得到相应的事件。
request
每次请求产生一个bean
session
每个用户session可以产生一个新的bean,不同用户之间的bean互相不影响
globalSession
作用和session类似,只是使用portlet的时候使用。
测试用例

因为平时使用SPRING MVC开发的时候比较多,有必要了解清楚怎么去调用这几种作用域。

1,定义不同作用域的java类

 

 

@Component
@Scope( "session")
public class SessionObj {

}
@Component
@Scope( "request")
public class RequestObj {

}
@Component
@Scope( "prototype")
public class PrototypeObj {

}
@Component
@Scope( "singleton")
public class SingletonObj {

}

 2,注入到controller,由于controller是单例的,因此必须通过实现ApplicationContextAware接口,直接从容器中取出对象。

 

因此测试的controller是:

 

@Controller
public class IndexController implements ApplicationContextAware {

	private RequestObj RequestObj;

	private SessionObj SessionObj;

	private PrototypeObj PrototypeObj;

	private SingletonObj SingletonObj;

	private ApplicationContext applicationContext;

	@RequestMapping("/")
	@ResponseBody
	public String index() {
		print();
		return "Welcome";
	}

	public void print() {
		System.out.println("first  time singleton is :" + getSingletonObj());
		System.out.println("second time singleton is :" + getSingletonObj());

		System.out.println("first  time prototype is :" + getPrototypeObj());
		System.out.println("second time prototype is :" + getPrototypeObj());

		System.out.println("first  time request is :" + getRequestObj());
		System.out.println("second time request is :" + getRequestObj());

		System.out.println("first  time session is :" + getSessionObj());
		System.out.println("second time session is :" + getSessionObj());
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
	}

	public RequestObj getRequestObj() {
		return applicationContext.getBean(RequestObj.class);
	}

	public void setRequestObj(RequestObj requestObj) {
		RequestObj = requestObj;
	}

	public SessionObj getSessionObj() {
		return applicationContext.getBean(SessionObj.class);
	}

	public void setSessionObj(SessionObj sessionObj) {
		SessionObj = sessionObj;
	}

	public PrototypeObj getPrototypeObj() {
		return applicationContext.getBean(PrototypeObj.class);
	}

	public void setPrototypeObj(PrototypeObj prototypeObj) {
		PrototypeObj = prototypeObj;
	}

	public SingletonObj getSingletonObj() {
		return applicationContext.getBean(SingletonObj.class);
	}

	public void setSingletonObj(SingletonObj singletonObj) {
		SingletonObj = singletonObj;
	}

}

 

 

3,运行结果:

 

//使用chrome第一次打印数据:
first  time singleton is :com.fb.po.SingletonObj@1e3223e
second time singleton is :com.fb.po.SingletonObj@1e3223e
first  time prototype is :com.fb.po.PrototypeObj@3e683f
second time prototype is :com.fb.po.PrototypeObj@12e18d7
first  time request is :com.fb.po.RequestObj@1d45706
second time request is :com.fb.po.RequestObj@1d45706
first  time session is :com.fb.po.SessionObj@9a6b2e
second time session is :com.fb.po.SessionObj@9a6b2e



//使用chrome打印第二次数据
first  time singleton is :com.fb.po.SingletonObj@1e3223e
second time singleton is :com.fb.po.SingletonObj@1e3223e
first  time prototype is :com.fb.po.PrototypeObj@122e5be
second time prototype is :com.fb.po.PrototypeObj@192add
first  time request is :com.fb.po.RequestObj@4d1b6c
second time request is :com.fb.po.RequestObj@4d1b6c
first  time session is :com.fb.po.SessionObj@9a6b2e
second time session is :com.fb.po.SessionObj@9a6b2e



//使用IE打印第三次数据
first  time singleton is :com.fb.po.SingletonObj@1e3223e
second time singleton is :com.fb.po.SingletonObj@1e3223e
first  time prototype is :com.fb.po.PrototypeObj@10f1ecb
second time prototype is :com.fb.po.PrototypeObj@1aeb990
first  time request is :com.fb.po.RequestObj@18a1e7
second time request is :com.fb.po.RequestObj@18a1e7
first  time session is :com.fb.po.SessionObj@12d5c55
second time session is :com.fb.po.SessionObj@12d5c55

 

 

4,结果分析:

从结果来看,单例的bean的三次的数据都是打印一样的(默认的bean的级别就是单例);

prototype的bean每次的数据都是不一样的,每次请求的时候调用两次结果都不一样。

request的bean在每次request的时候都不一致,但是同一次request返回的数据是一致的。

session的bean在前两次结果一致,最后一次数据不一致,和session的节奏是一致的。

 

5,欠缺

 

网络上说必需配置

<listener> 
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 
</listener> 

 但是没配置也好使……好奇……

 

最后一种作用域是适用于portlet,没试验,据说是在多个session之间可以共享,效果等同于全局变量。

 

 

 

感谢朴老师,我们有了另外一种测试方式

测试代码

 

@Controller
@Scope("prototype")
public class SecondController {

	@Autowired
	private RequestObj RequestObj;

	@Autowired
	private SessionObj SessionObj;

	@Autowired
	private PrototypeObj PrototypeObj;

	@Autowired
	private SingletonObj SingletonObj;

	@RequestMapping("/test")
	@ResponseBody
	public String index() {
		print();
		return "Welcome";
	}

	public void print() {
		System.out.println("first  time singleton is :" + SingletonObj);
		System.out.println("second time singleton is :" + SingletonObj);

		System.out.println("first  time prototype is :" + PrototypeObj);
		System.out.println("second time prototype is :" + PrototypeObj);

		System.out.println("first  time request is :" + RequestObj);
		System.out.println("second time request is :" + RequestObj);

		System.out.println("first  time session is :" + SessionObj);
		System.out.println("second time session is :" + SessionObj);
	}

}

 

打印的结果是:

first  time singleton is :com.fb.po.SingletonObj@83ca19
second time singleton is :com.fb.po.SingletonObj@83ca19
first  time prototype is :com.fb.po.PrototypeObj@4961d6
second time prototype is :com.fb.po.PrototypeObj@4961d6
first  time request is :com.fb.po.RequestObj@1b6467f
second time request is :com.fb.po.RequestObj@1b6467f
first  time session is :com.fb.po.SessionObj@1ce5037
second time session is :com.fb.po.SessionObj@1ce5037


first  time singleton is :com.fb.po.SingletonObj@83ca19
second time singleton is :com.fb.po.SingletonObj@83ca19
first  time prototype is :com.fb.po.PrototypeObj@1089e03
second time prototype is :com.fb.po.PrototypeObj@1089e03
first  time request is :com.fb.po.RequestObj@be12fc
second time request is :com.fb.po.RequestObj@be12fc
first  time session is :com.fb.po.SessionObj@1ce5037
second time session is :com.fb.po.SessionObj@1ce5037


first  time singleton is :com.fb.po.SingletonObj@83ca19
second time singleton is :com.fb.po.SingletonObj@83ca19
first  time prototype is :com.fb.po.PrototypeObj@a7b674
second time prototype is :com.fb.po.PrototypeObj@a7b674
first  time request is :com.fb.po.RequestObj@bb9ce2
second time request is :com.fb.po.RequestObj@bb9ce2
first  time session is :com.fb.po.SessionObj@138ea04
second time session is :com.fb.po.SessionObj@138ea04

 

 

结果分析:

singleton , request 和session结果都是上面一致,但是prototype结果是和request效果一致的。所以如果要拿到prototype类型的数据的话,应该每次需要都去容器中去拿,而不是注入。

 

 

另,现在开发应用大多数都是无状态的,所以单例多线程是比较好的实现方式,多例的比较有利于保存状态,完全没必要。不过试验JVM垃圾回收,这不就是传说中朝生夕灭的对象吗。

参考http://haohaoxuexi.iteye.com/blog/1190526

 

分享到:
评论
2 楼 85977328 2014-03-26  
另外不太清楚portlet是啥东西
1 楼 85977328 2014-03-26  
文章写的太好了。转载了~~~

相关推荐

    Spring 的bean的作用域总结

    Spring 的bean的作用域总结,详细的总结了 Spring 的bean的作用域

    spring Bean的作用域之间有什么区别1

    Spring Bean 的作用域之间有什么区别:Bean的作用域: 可以通过scope 属性来指定bean的作用域 ①singleton: 默认值。当IOC容器

    spring的bean作用域

    在Spring中,有五种主要的Bean作用域: 1. **Singleton作用域**: - Singleton是Spring默认的Bean作用域。这意味着,无论何时,只要Spring容器被初始化,它都会创建一个Bean实例,并将其缓存起来。后续对相同ID的...

    详解Spring中bean的作用域

    让 Spring 容器释放被 singleton 作用域 bean 占用资源的一种可行方式是,通过使用 bean 的后置处理器,该处理器持有要被清除的 bean 的引用。 3. Request 作用域 Request 作用域是指该针对每一次 HTTP 请求都会...

    spring bean 的作用域(scope)

    spring bean 的作用域(scope), SPringle bean的作用域

    详解Spring中Bean的生命周期和作用域及实现方式

    Spring中Bean的生命周期和作用域及实现方式 Spring是一个非常流行的Java应用程序框架,它提供了一个灵活的机制来管理Bean的生命周期和作用域。Bean的生命周期和作用域是Spring框架中两个非常重要的概念,它们决定了...

    Spring框架中Bean的生命周期 Spring中Bean有几种作用域

    接下来,我们讨论Spring中Bean的几种作用域: 1. **单例(Singleton)**:这是默认的作用域,Spring容器只会创建一个Bean实例,所有对Bean的请求都会返回同一个实例。 2. **原型(Prototype)**:在每次请求时,...

    JSP 中Spring Bean 的作用域详解

    JSP 中Spring Bean 的作用域详解 Bean元素有一个scope属性,用于定义Bean的作用域,该属性有如下五个值: 1&gt;singleton: 单例模式,在整个spring IOC容器中,单例模式作用域的Bean都将只生成一个实例。一般Spring...

    Spring实战之Bean的作用域singleton和prototype用法分析

    在Spring框架中,Bean的作用域是决定如何管理和创建Bean实例的关键概念。本篇文章将深入探讨两种主要的作用域:singleton和prototype,并通过实例分析其用法和注意事项。 首先,`singleton`是Spring默认的作用域,...

    Spring中Bean的作用域

    NULL 博文链接:https://huangminwen.iteye.com/blog/1486717

    Spring容器中Bean的作用域编程开发技术共3页.pd

    在Spring框架中,Bean的作用域是其生命周期管理的关键部分,它决定了Bean的创建、共享以及销毁方式。本篇内容将深入探讨Spring容器中Bean的作用域编程开发技术,以帮助开发者更好地理解和利用这些特性来优化应用的...

    spring bean的生命周期

    - **XML配置**:在传统的Spring应用中,Bean的定义通常写在XML配置文件中,如`springbean-xml`中的配置。 - **注解配置**:使用`@Component`,`@Service`,`@Repository`和`@Controller`注解标记类,配合`@...

    Spring实战之Bean的作用域request用法分析

    主要介绍了Spring实战之Bean的作用域request用法,结合实例形式分析了spring中Bean的request作用域相关使用技巧与操作注意事项,需要的朋友可以参考下

    Spring Bean的作用域.docx

    Spring提供了五种不同的Bean作用域,每种都有其特定的使用场景和行为。 1. **Singleton作用域**:这是Spring的默认作用域,意味着无论何时从容器中请求一个特定的Bean,都会返回同一个实例。在配置文件中,可以使用...

    Spring Bean 作用域.pdf

    spring Bean 作用域.pdf

    Spring Bean重复执行两次(实例被构造两次)问题分析

    综上所述,Spring Bean重复执行两次的问题通常是由于配置错误、依赖注入循环、初始化回调的不当使用、静态工厂方法的误用、AOP代理的配置问题或是Bean作用域设置不准确导致的。通过仔细检查和修正这些问题,可以避免...

    01.Spring Bean的作用域代码.zip

    01.Spring Bean的作用域代码

    Spring Bean 加载顺序 .

    对于Singleton作用域的Bean,Spring会在容器启动时一次性实例化所有Bean。实例化顺序基于Bean的依赖关系和`@DependsOn`注解。如果Bean之间没有依赖关系,Spring将按照Bean定义的顺序实例化。对于Prototype作用域,...

    spring-aware接口实现与bean作用域(spring多容器层面)

    关于`bean的作用域`,Spring支持多种Bean的作用域,包括单例(Singleton)、原型(Prototype)、会话(Session)和请求(Request)。这些作用域定义了Bean的生命周期和创建行为: 1. **单例(Singleton)**:默认...

Global site tag (gtag.js) - Google Analytics