Spring容器中Bean的作用域之singleton和prototype
2016-08-10 15:48
471 查看
当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下5种作用域,在这里主要说的就是大名鼎鼎的singleton–单例模式和prototype–原型模式,这两个Bean的作用域也是在Spring中比较常见的。其中关于单例模式的概念为我的博客中有写到,可以出门右转去找找,这里在不赘述。
一、singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例;注意这里的Spring singleton模式是默认缺省的饿汉模式,启容器时(即实例化容器时),为所有spring配置文件中定义的bean都生成一个实例。
核心代码如下:
可是这样做会导致系统的开销比较大,为了不占用过大的资源或者是减少开销,一般我会在spring中添加缺省文件:
将系统默认的饿汉模式转换成懒汉模式,也就是在第一次请求的时候我们才生成一个实例,在之后的使用中继续调用即可
核心代码如下:
二、prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例。
对于singleton作用域的 Bean,每次请求该Bean都将获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个Bean被设置成 prototype作用域,程序每次请求该id的Bean,Spring都会新建一个Bean实例,然后返回给程序。在这种情况下,Spring容器仅仅 使用new 关键字创建Bean实例,一旦创建成功,容器不在跟踪实例,也不会维护Bean实例的状态。
如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。
测试代码:
执行结果:
从结果可以看出,正如上文所述:对于singleton作用域的Bean,每次请求该id的Bean,都将返回同一个实例,而prototype作用域的Bean, 每次请求都将产生全新的实例。
注意:早期指定Bean的作用域也可通过singleton属性指定,该属性只接受两个属性值:true和false,分别代表singleton和prototype的作用域。使用singleton属性则无法指定其他三个作用域。实际上Spring2.X不推荐使用singleton属性指定Bean的作用域,singleton属性是Spring 1.2.X的使用方式。
一、singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例;注意这里的Spring singleton模式是默认缺省的饿汉模式,启容器时(即实例化容器时),为所有spring配置文件中定义的bean都生成一个实例。
核心代码如下:
class Bean { private static final Bean theBean; private Bean() {} public static Bean getBean() { return theBean; } }
可是这样做会导致系统的开销比较大,为了不占用过大的资源或者是减少开销,一般我会在spring中添加缺省文件:
<beans default-lazy-init="true">
将系统默认的饿汉模式转换成懒汉模式,也就是在第一次请求的时候我们才生成一个实例,在之后的使用中继续调用即可
核心代码如下:
class Bean { private static final Bean theBean; private Bean() {} public static Bean getBean() { if (theBean == null) { theBean = new Bean(); } return theBean; } }
二、prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例。
对于singleton作用域的 Bean,每次请求该Bean都将获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个Bean被设置成 prototype作用域,程序每次请求该id的Bean,Spring都会新建一个Bean实例,然后返回给程序。在这种情况下,Spring容器仅仅 使用new 关键字创建Bean实例,一旦创建成功,容器不在跟踪实例,也不会维护Bean实例的状态。
如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。
测试代码:
<!-- 默认的作用域:singleton --> <bean id="p1" class="com.cxg.User" /> <!-- 指定的作用域:prototype --> <bean id="p2" class="com.cxg.User" scope="prototype" />
public class BeanTest { public static void main(String args[]) { //加载类路径下的beans.xml文件以初始化Spring容器 ApplicationContext context = new ClassPathXmlApplicationContext(); //分两次分别取同一个Bean,比较二者是否是同一个对象 System.out.println(context.getBean("p1") == context.getBean("p1")); System.out.println(context.getBean("p2") == context.getBean("p2")); } }
执行结果:
true false
从结果可以看出,正如上文所述:对于singleton作用域的Bean,每次请求该id的Bean,都将返回同一个实例,而prototype作用域的Bean, 每次请求都将产生全新的实例。
注意:早期指定Bean的作用域也可通过singleton属性指定,该属性只接受两个属性值:true和false,分别代表singleton和prototype的作用域。使用singleton属性则无法指定其他三个作用域。实际上Spring2.X不推荐使用singleton属性指定Bean的作用域,singleton属性是Spring 1.2.X的使用方式。
相关文章推荐
- spring开发_spring中Bean的作用域_singleton_prototype
- spring开发_spring中Bean的作用域_singleton_prototype
- [原创]java WEB学习笔记99:Spring学习---Spring Bean配置:自动装配,配置bean之间的关系(继承/依赖),bean的作用域(singleton,prototype,web环境作用域),使用外部属性文件
- 使用Spring(七)集合合并、bean的作用域(prototype,singleton)
- 【Spring】bean的作用域(@Scope) - singleton、prototype
- spring开发_spring中Bean的作用域_singleton_prototype
- Spring 中 bean 的作用域:singleton;prototype;WEB 环境作用域
- Spring容器中Bean的作用域
- spring中bean的作用域与懒加载及初始化方法和销毁方法以及spring容器的正常关闭
- spring配置文件中bean中scope属性prototype和singleton
- Spring容器中Bean的作用域
- Spring容器中Bean的作用域
- 《转》详解Spring中bean的scope singleton prototype request...
- spring bean scope=prototype/singleton的差别
- spring中bean的作用域与懒加载及初始化方法和销毁方法以及spring容器的正常关闭
- Spring容器中Bean的作用域
- 关于spring容器scope="singleton"或scope=“prototype”理解
- 一则spring容器启动死锁问题(DefaultListableBeanFactory/DefaultSingletonBeanRegistry)
- 10010---bean 的作用域:singleton;prototype;WEB 环境作用域
- Spring Bean Scope Singleton Prototype 相互引用说明