Spring学习(二)--- Bean 作用域
概述
本文介绍的Spring 中bean的作用域。
问题 :
- bean的作用域有几种,有那些应用场景
bean 装配过程
下图为bean在容器中从创建到销毁的若干阶段。

bean 作用域
作用域介绍
下面的表格显示的就是bean的作用域,其中单例模式(singleton)下是bean 默认的作用域;prototype 确定一个类,衍生出多个实例。request 和 session 和 http 请求有关;application 的作用域和 ServletContext 有关。

下面展示的是 singleton 和 prototype 两种作用域的示意图。

singleton

prototype
为bean指定作用域
下面是两种方式为bean指定了作用域。
//假如你使用组件扫描发现和声明 bean
@Component
@Scope(ConfigurationBeanFactory.SCOPE_PROTOTYPE)
public class {
....
} <!--使用XML 的方式就像下面所示-->
<bean id="notepad"
class="com.myapp.Notpad"
scope="prototype"
/>
作用域的bean 作为依赖
singleton 和 prototype 作用域的bean 注入到另外的 bean 时不需要使用代理,而request,session 和自定义作用域的bean
作为依赖时需要使用代理。
下面以“购物-购物车”为应用场景为例子。
有一个bean代表用户的购物车。 如果购物车是单例的话, 那么将会导致所有的用户都会向同一个购物车中添加商品。 另一方
面, 如果购物车是原型作用域的, 那么在应用中某一个地方往购物车中添加商品, 在应用的另外一个地方可能就不可用了, 因为在这里
注入的是另外一个原型作用域的购物车。
假设我们要将ShoppingCart bean注入到单例StoreService bean的Setter方法中, 如下所示 :
@Component
public class StoreService{ @Autowired
public void setShoppingCard(ShopperingCar car){
this.shopperingcar = car;
}
}
我们的购物车bean作用域已经确定是 session 的,而StoreService 作用域是 singleton
//购物车bean
@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION,
proxyMode = ScopeProxyMode.INTERFACES)
public ShopperingCart cart(){
...
}
可以看到我们发的Scope 注解中出现了一个 proxyMode 的属性,下面解释一下使用这个属性的原因 :
因为StoreService是一个单例的bean, 会在Spring应用上下文加载的时候创建。 当它创建的时候, Spring会试图将ShoppingCart bean注入到 setShoppingCart() 方法中。 但是ShoppingCart bean是会话作用域的, 此时并不存在。 直到某个用户进入系统, 创建了会话之后, 才会出现ShoppingCart实例。
另外, 系统中将会有多个 ShoppingCart 实例: 每个用户一个。 我们并不想让Spring注入某个固定的 ShoppingCart 实例到StoreService 中。 我们希望的是当 StoreService 处理购物车功能时, 它所使用的 ShoppingCart 实例恰好是当前会话所对应的那一个。Spring并不会将实际的 ShoppingCart bean 注入到 StoreService 中, Spring会注入一个到 ShoppingCart bean 的代理, 下图所示。 这个代理会暴露与 ShoppingCart 相同的方法, 所以 StoreService会认为它就是一个购物车。 但是, 当StoreService调用 ShoppingCart 的方法时, 代理会对其进行懒解析并将调用委托给会话作用域内真正的ShoppingCart bean。
需要注意的是如果ShoppingCart是一个具体的类的话, Spring就没有办法创建基于接口的代理了。 此时, 它必须使用CGLib来生成基于类的代理。 所以, 如果bean类型是具体类的话, 我们必须要将 proxyMode 属性设置为 ScopedProxyMode.TARGET_CLASS, 以此来表明要以生成目标类扩展的方式创建代理。

下面我们看一下XML 方式的装配 :
<bean id = "card" class="com.myapp.ShoppingCart" scop="session">
<aop:scope-proxy proxy-target-class = "false">
</bean>
注意XML文件需要添加 aop 的命名空间。
参考资料
- 《Spring in Action》
- spring.io doc
Spring学习(二)--- Bean 作用域的更多相关文章
- spring 学习之 bean 的注入方式 property和constructor-arg的使用方式
spring 学习之 bean 的注入方式 property和constructor-arg的使用方式. bean的注入方式: property 注入是: 通过setxx方法注入. construct ...
- Spring入门(3)-Spring命名空间与Bean作用域
Spring入门(3)-Spring命名空间与Bean作用域 这篇文章主要介绍Spring的命名空间和Bean作用域 0. 目录 Spring命名空间 Bean作用域 1. Spring命名空间 在前 ...
- Spring 学习笔记 Bean的作用域
在配置文件中定义Bean时,用户不但可以配置Bean的属性值以及相互之间的依赖关系,还可以定义Bean的作用域.作用域将对Bean的生命周期和创建方式产生影响.在低版本的Spring中,仅有两个作用域 ...
- Spring学习(二):Spring支持的5种Bean Scope
序言 Scope是定义Spring如何创建bean的实例的.Spring容器最初提供了两种bean的scope类型:singleton和prototype,但发布2.0以后,又引入了另外三种scope ...
- Spring学习(二)--装配Bean
一.Spring装配机制 Spring提供了三种主要的装配机制: 1.在XML中进行显示配置 2.在Java中进行显示配置 3.隐式的bean发现机制和自动装配--自动化装配bean Spring可以 ...
- Spring学习二:Spring Bean 定义
Bean 定义 被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的.bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象.这些 bean 是 ...
- Spring IOC 之Bean作用域
当你创建一个bean定义的时候,你创建了一份通过那种bean定义的bean的创建类的真正实力的处方.bean的定义是一个处方 的想法是很重要的的.因为这意味着,对于一个类你可以创建很多对象实例从一个单 ...
- Spring系列(二) Bean装配
创建应用对象之间协作关系的行为称为装配(wiring), 这也是DI的本质. Spring中装配Bean的方式 Spring提供了三种装配Bean的方式. 隐式的Bean发现机制和自动装配 Java ...
- Spring之配置文件bean作用域的详细介绍
Spring的配置文件applicationContext.xml中bean作用域的详细介绍: 1:对象的创建:单例和多例 scope="singleton",默认值 ...
- Spring 学习之bean的理解
前言:对于使用Spring框架的开发人员来说,我们主要做的主要有两件事情:①开发Bean;②配置Bean;而Spring帮我们做的就是根据配置文件来创建Bean实例,并调用Bean实例的方法来完成“依 ...
随机推荐
- Django_Restframwork_序列号组件
第一种序列化方式. 第二种方法通过Model_to_dict方法进行创建 第三种方式序列号组件Serializers: 第四种方法序列化 五.ModelSerializer组件. POST校验 PU ...
- python--面向对象(02)
1.类的成员 在类中你能写的所有内容都是类的成员 class 类名: # 方法 def __init__(self, 参数1, 参数2....): # 属性变量量 self.属性1 = 参数1 sel ...
- django入门-表单-part4
尊重作者的劳动,转载请注明作者及原文地址 http://www.cnblogs.com/txwsqk/p/6514113.html 完全翻译自官方文档 https://docs.djangoproje ...
- Linux 中排除掉筛选的文件
以下命令以网站目录www为例做介绍,有时候更新网站的时候需要保留比如图片目录,或者其他目录就需要这样的操作 实例一: 删除文件夹内所有文件只保留一个文件命令 [root@linuxzgf www]# ...
- python接口自动化2-发送post请求详解(二)
前言 发送post的请求参考例子很简单,实际遇到的情况却是很复杂的,首先第一个post请求肯定是登录了,但登录是最难处理的.登录问题解决了,后面都简单了. 一.查看官方文档 1.学习一个新的模块,其实 ...
- Working with Metal—Overview
看完这个 WWDC 之后的总结. Metal 可以在单位时间内提供 10 倍的 draw call 调用. Background About Draw Call 每一次 draw call 调用都必须 ...
- 考试题T3
题意分析 这题一看没有什么思路 幸好我们机房的红太阳\(ghj1222\)切了这道题 首先我们考虑风跑一个来回之后人怎么样 就是跑了一个区间 也就是风跑了若干个来回之后 人跑了若干个区间 所以我们考虑 ...
- Centos7.4下安装JDK1.8
在安装JDk之前将Linux自带的JDK卸载 查询是否携带JDK rpm -qa | grep java删除自带的JDK rpm -e --nodeps jdk文件 将下载好的JDK传到Linux. ...
- 【ASP.NET】DataTable导出EXCEL,弹窗提示下载保存(完整代码)
//新建ASPX protected void Page_Load(object sender, EventArgs e) { DataTable dt = new DataTable(); Data ...
- MySQL之试图、触发器、事务、存储过程、函数
阅读目录 一.视图 二.触发器 三.事务 四.存储过程 五.函数 六.流程控制 一.视图 视图是一个虚拟表(非真实存在),是跑到内存中的表,真实表是硬盘上的表,怎么就得到了虚拟表,就是你查询的结果,只 ...