Spring实战学习笔记——bean的作用域
来源:互联网 发布:什么软件小额贷款成功 编辑:程序博客网 时间:2024/05/17 20:00
bean的作用域
在默认情况下,Spring应用上下文中所有的bean都是以单例(singleton)的形式创建的。无论一个给定的bean被注入多少次,每次所注入的实例都是同一个实例。
在大多数情况下,单例bean是很理想的。但是如果使用的类是易变的(mutable),他们自身会有一些特定的状态,在这种情况下重用bean变得既不安全,由此看来此时单例bean就不再是什么好主意了。Spring提供了多中作用域,可以基于这些作用域创建bean,包括:
- 单例(Singleton):在整个应用中,只创建bean的一个实例。
- 原型(Prototype):每次注册如或者通过Spring上下文获取的时候,都会创建一个新的bean实例。
- 会话(Session):在Web应用中,为每个会话创建一个bean实例。
- 请求(Request):在Web应用中,为每个请求创建一个bean实例。
默认情况下创建的bean的作用域是单例的,但是对于易变的类型并不合适,如果使用其他的的作用域需要使用@Scope
注解,它可以与@Compoent
或@Bean
一起使用。例如:
@Component@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)public class Notepad {……}
这里使用了ConfigurableBeanFactory
类的SCOPE_PROTOTYPE
常量设置了原型作用域。当然也可以使用@Scope("prototype")
,但是使用SCOPE_PROTOTYPE
常量更加安全并且不易出错。如果想要在Java配置将Notepad
声明为bean,可以使用@Scope
和@Bean
来指定所需的作用域。如果使用XML来配置bean的话,可以使用<bean>
元素的scope属性来设置作用域:
无论是用那种方式来声明原型作用域,每次注入或从Spring应用上下文中检索该bean的时候,都会创建自己的实例。
使用会话和请求作用域
在Web应用中,如果能够实例化在会话和请求范围内共享的bean,那将是非常有价值的事情。
会话作用域可以给用户以最大的关联性,在一个会话中都持有同一个相同的bean。例如在电子商务应用中,用户在购物过程中应该都持有属于自己的唯一的一个购物车,在这个场景下,使用会话作用域是最合适不过的了。使用@Scope
注解。
@Component@Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.INTERFACES)public ShoppingCart cart() {……}
在这里我们将value的值设置为了WebApplicationContext
中的SCOPE_SESSION
常量(它的值是session)。这会告诉Spring为Web应用中的每个会话创建一个ShoppingCart实例。这样会创建多个ShppoingCart bean的实例,但是对于给定的会话只会创建一个实例,在当前会话的相关的操作中,这个bean实际上相当于是单例的。
通过上面的分析,了解到系统中将有多个ShoppingCart实例,我们并不想让Spring将某个固定的ShoppingCart实例注入进去。希望当用户使用购物车功能的时候,所使用的ShoppingCart恰好是当前会话所对应的哪一个。
实际上,Spring在处理bean的时候,并不会将实际的bean注入到相应的位置,Spring会注入到一个ShoppingCart bean的代理。如下图所示:
图中的代理会暴露于ShoppingCart相同的方法,当其他类调用其中的方法的时候,代理会对其进行懒解析将其委托给作用域中真正的bean。
这里需要对proxyMode
属性进行说明:如果此时ShoppingCart 为一个接口,则需要使用ScopedProxyMode.INTERFACES
(这也是最理想的代理模式)。但是如果其作用的为一个具体的类,Spring就无法创建基于接口的代理,需要将proxyMode
属性设置为ScopedProxyMode.TARGET_CLASS
,以便生成目标扩展的方式创建代理。请求作用域的bean与会话作用域bean面临相同的问题,所以同样需要一作用域代理的方式进行注入。
在XML中声明作用域代理
如果使用XML来声明会话或请求作用域的bean,可以利用<bean>
元素的scope属性设置作用域,并且需要使用Spring aop命名空间的一个新元素。它会告诉Spring为bean创建爱你一个作用域代理,且默认情况下会使用CGLib创建目标类的代理。但可以将proxy-target-class
属性设置为false,进而要求它生成基于接口的代理。例如:
- Spring实战学习笔记——bean的作用域
- Spring 学习笔记 Bean的作用域
- 学习笔记:Spring Bean的作用域
- spring笔记——bean的作用域
- spring学习笔记(6)——bean的作用域
- Spring学习笔记(二)Bean的作用域
- JavaWeb学习笔记之Spring中bean的作用域
- 【Spring学习笔记五】-Bean的作用域
- SpringInAction学习笔记:Spring bean的作用域
- Spring学习笔记之Bean的作用域
- Spring学习笔记之Bean的作用域
- spring学习笔记五 bean的作用域
- Spring学习笔记(5.Spring Bean装配之Bean的配置项及作用域)
- spring—bean的作用域
- Spring实战笔记——Bean的高级装配
- Spring实战笔记——装配Bean
- 11.笔记JAVA Spring框架学习————Bean作用域
- spring学习笔记(1) 配置spring bean的作用域 创建方法和销毁方法
- 设计模式-抽象工厂模式(创建型模式)
- Caffe 自定义数据输入层
- Kinect识别右手,模拟点击按钮
- 谈谈你对JVM的理解?
- 计算机视觉 | 复杂环境背景下,车辆识别如何实现
- Spring实战学习笔记——bean的作用域
- Android Studio导入第三方类库、jar包和so库
- Qt鼠标绘制平滑曲线解决方案(2)
- kafka-linux集群搭建小结
- 使用grub2和u盘不刻录iso安装fedora 26 x86_64
- List<Map<String, String>>遍历相同数据合并(map里面某个key相同则合并数据)
- 在linux使用锐捷客户端上网(华中科技大学)
- hadoop从入门到精通第一节Hadoop完全分布式安装部署
- 非activity跳activity技巧