一、前言

本文承接上一节:Spring_总结_04_高级配置(三)之处理歧义

1.单例bean

Spring应用上下文中所有的bean默认都是单例的。也就是说,不管一个bean被注入到其他bean多少次,每次注入的都是同一个实例。

2.有状态bean与无状态bean

单例bean适用于那些无状态的对象,在多数情况下,单例bean是很理想的方案。但是有时候,你所使用的类是易变的,他会保持一些状态(有状态),因此重用是不安全的。

举个例子:

这段时间在做一个脚本引擎,需要在java中执行js代码。当我在程序中注入一个单例的脚本引擎,并用这个脚本引擎去重复执行一段js代码。

第一次执行的时候,能正常执行;第二次执行的时候,却报js中定义的一个对象已存在。

这就是因为在第二次执行的时候,单例的脚本引擎中已经包含了第一次执行时的状态,即第一次执行之后,js中的对象已存在于脚本引擎中,因此导致第二次执行时出现重复定义的错误。

在这个例子中,我们需要的其实是,每次执行的时候单独为我创建一个bean,而不是每次使用的都是同一个bean。

二、bean的作用域

Spring定义了多种作用域,可以基于这些作用域创建bean。

1 单例(Singleton) 在整个应用中,只创建bean的一个实例
2 原型(Prototype) 每次注入或者通过Spring应用上下文获取的时候,都会一个新的bean实例。
3 会话(Session) 在Web应用中,为每个会话创建一个bean实例
4 请求(Request) 在Web应用中,为每个请求创建一个bean实例

单例是默认的作用域,这对于易变类型,并不合适,这是就要为bean声明一个@Scope注解,可配合@Component或@Bean一起使用。

1.Prototype

为bean声明如下注解,即可创建原型bean

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

或者

@Scope("prototype")

示例如下:

(1)自动装配时

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Notepad{...}

(2) Java 配置时

@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Notepad notepad(){
return new Notepad();
}

(3) xml 配置

<bean  id="notepad" class="com.myapp.Notepad"
scope="prototype" />

2.Session

为bean声明如下注解,即可创建会话bean

@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION,
proxyMode=ScopedProxyMode.TARGET_CLASS)
public ShoppingCart cart(){...}

假设,我们要将ShoppingCart bean 注入到单例 StoreService bean的 Setter方法中,如下所示:

@Coponent
public class StoreService{ @Autowired
public void setShoppingCart( ShoppingCart shoppingCart){
this.shoppingCart = shoppingCart;
} }

  因为storeService是一个单例bean,会在Spring应用上下文加载的时候创建。当它创建的时候,Spring会注入一个到ShoppingCart的代理。当StoreService调用ShoppingCart的方法时,代理会对其进行懒解析并将调用委托给会话作用域内真正的ShoppingCart bean。  

  注意到proxyMode属性,ScopedProxyMode.TARGET_CLASS 表明将创建一个基于目标类的代理。

而若ShoppingCart是一个接口时,则需要使用 ScopedProxyMode.INTERFACES,表明要创建一个实现ShoppingCart接口的代理,并将调用委托给实现bean。

3.Request

为bean声明如下注解,即可创建请求bean

@Component
@Scope(value=WebApplicationContext.SCOPE_REQUEST,
proxyMode=ScopedProxyMode.TARGET_CLASS)
public ShoppingCart cart(){...}

三、参考资料

1.《Spring 实战 (第四版)》

最新文章

  1. 应如何取B/S的B端的IP
  2. RabbitMQ常用命令行
  3. Loadrunner---解决乱码问题
  4. erlang学习笔记(文件操作)
  5. [c++] Pieces of knowledge
  6. [java] 汇率换算器实现(2)
  7. Apache CXF实现WebService发布和调用
  8. python程序性能分析
  9. 微博广告推荐中有关Hadoop的那些事
  10. Code Review中应该关注的点
  11. IT学习网站
  12. dede文章插入分页符不起作用,编辑器中出现分页符,导致文章显示不全
  13. INT_MAX (2147483647) 和INT_MIN (-2147483648)溢出
  14. 全废话SQL Server统计信息(1)——统计信息简介
  15. Leetcode_257_Binary Tree Paths
  16. SpringCloud启动类指定扫描包路径
  17. RF:操作笔记
  18. Python集合(set)类型的操作 (转)
  19. 列表的append方法和extend方法
  20. 转:HDFS运行原理

热门文章

  1. Ubuntu 14.04上安装WineTMQQ2013麒麟版
  2. Dapper-Extensions
  3. HTTP首部信息说明
  4. 剑指offer 面试7题
  5. 字节流和字符流 in Java
  6. 软件工作考核项(zcl)——
  7. Linux服务器iops性能测试-iozone
  8. Swift 学习 用 swift 调用 oc
  9. Python编程-函数进阶二
  10. samtools使用过程中出现的问题