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实例的方法来完成“依 ...
随机推荐
- C博客第01次作业---顺序,分支结构
1.本章学习总结 1.1 思维导图 1.2本章学习体会及代码量学习体会 1.2.1学习体会 经过了这一周的学习,从一开始对C语言一无所知,到现在能够写出基本的代码,感到非常开心. 学习C语言也并非想象 ...
- 微信小程序下可以使用的MD5以及AES加密(通用)
两段代码都来自网络 ,在小程序下的加解密结果与CS/BS等算出的结果都一致,支持汉字. 一.MD5: var rotateLeft = function (lValue, iShiftBits) { ...
- 学习笔记|Java 教程|菜鸟教程
一.Java 教程 1.Java 教程 Java 在线工具 JDK 1.6 在线中文手册 我的第一个 JAVA 程序 创建文件 HelloWorld.java(文件名需与类名一致), 代码如下: pu ...
- 《快学Scala》第五章 类
关于case class和普通class的区别,可以参考: https://www.iteblog.com/archives/1508.html
- MySQL中LOCATE用法
SELECT LOCATE('q', 'asqdfasdfser') 返回 3 SELECT LOCATE('q', 'asqdfasqdfser',4) 返回 8 SELECT * from my ...
- Python内置函数查询表——总结篇
Python3.5版本中的68个内置函数,按顺序逐个进行了自认为详细的解析,现在是时候进行个总结了.为了方便记忆,将这些内置函数进行了如下分类: 数学运算(7个) 类型转换(24个) ...
- python-------打印与字符串格式化
print python中每次执行print时都会在新的一行上开始.形如:print(’xiao') print('ming') 结果为:>>>xiao >>>mi ...
- SQL Server——存储过程(Stored Procedure)、事物、触发器
存储过程(proc 或 procedure) 存储过程(Stored Procedure),计算机用语,是一组为了完成特定功能的SQL语句集,是利用SQL Server所提供的Transact-SQL ...
- 使用GPIO监听中断
#include<stdlib.h> #include<stdio.h> #include<string.h> #include<unistd.h> # ...
- 任务调度SpringTask
一.什么是任务调度 在企业级应用中,经常会制定一些“计划任务”,即在某个时间点做某件事情,核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作.常见的任务调度框架有Quartz和Spri ...