Spring提供“singleton”和“prototype”两种基本作用域,另外提供“request”、“session”、“global session”三种web作用域;Spring还允许用户定制自己的作用域。

  一、singleton指“singleton”作用域的Bean只会在每个Spring IoC容器中存在一个实例,而且其完整生命周期完全由Spring容器管理。对于所有获取该Bean的操作Spring容器将只返回同一个Bean。

GoF单例设计模式指“保证一个类仅有一个实例,并提供一个访问它的全局访问点”,介绍了两种实现:通过在类上定义静态属性保持该实例和通过注册表方式。

1)通过在类上定义静态属性保持该实例:一般指一个Java虚拟机 ClassLoader装载的类只有一个实例,一般通过类静态属性保持该实例,这样就造成需要单例的类都需要按照单例设计模式进行编码;Spring没采用这种方式,因为该方式属于侵入式设计;代码样例如下:

java代码:

  1. package cn.javass.spring.chapter3.bean;
  2. public class Singleton {
  3. //1.私有化构造器
  4. private Singleton() {}
  5. //2.单例缓存者,惰性初始化,第一次使用时初始化
  6. private static class InstanceHolder {
  7. private static final Singleton INSTANCE = new Singleton();
  8. }
  9. //3.提供全局访问点
  10. public static Singleton getInstance() {
  11. return InstanceHolder.INSTANCE;
  12. }
  13. //4.提供一个计数器来验证一个ClassLoader一个实例
  14. private int counter=0;
  15. }

以上定义个了个单例类,首先要私有化类构造器;其次使用InstanceHolder静态内部类持有单例对象,这样可以得到惰性初始化好处;最后提供全局访问点getInstance,使得需要该单例实例的对象能获取到;我们在此还提供了一个counter计数器来验证一个ClassLoader一个实例。具体一个ClassLoader有一个单例实例测试请参考代码“cn.javass.spring.chapter3. SingletonTest”中的“testSingleton”测试方法,里边详细演示了一个ClassLoader有一个单例实例。

通过注册表方式: 首先将需要单例的实例通过唯一键注册到注册表,然后通过键来获取单例,让我们直接看实现吧,注意本注册表实现了Spring接口“SingletonBeanRegistry”,该接口定义了操作共享的单例对象,Spring容器实现将实现此接口;所以共享单例对象通过“registerSingleton”方法注册,通过“getSingleton”方法获取,消除了编程方式单例,注意在实现中不考虑并发:

java代码:

 
  1. package cn.javass.spring.chapter3;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import org.springframework.beans.factory.config.SingletonBeanRegistry;
  5. public class SingletonBeanRegister implements SingletonBeanRegistry {
  6. //单例Bean缓存池,此处不考虑并发
  7. private final Map<String, Object> BEANS = new HashMap<String, Object>();
  8. public boolean containsSingleton(String beanName) {
  9. return BEANS.containsKey(beanName);
  10. }
  11. public Object getSingleton(String beanName) {
  12. return BEANS.get(beanName);
  13. }
  14. @Override
  15. public int getSingletonCount() {
  16. return BEANS.size();
  17. }
  18. @Override
  19. public String[] getSingletonNames() {
  20. return BEANS.keySet().toArray(new String[0]);
  21. }
  22. @Override
  23. public void registerSingleton(String beanName, Object bean) {
  24. if(BEANS.containsKey(beanName)) {
  25. throw new RuntimeException("[" + beanName + "] 已存在");
  26. }
  27. BEANS.put(beanName, bean);
  28. }
  29. }

Spring是注册表单例设计模式的实现,消除了编程式单例,而且对代码是非入侵式。

接下来让我们看看在Spring中如何配置单例Bean吧,在Spring容器中如果没指定作用域默认就是“singleton”,配置方式通过scope属性配置,具体配置如下:

java代码:

  1. <bean  class="cn.javass.spring.chapter3.bean.Printer" scope="singleton"/>

Spring管理单例对象在Spring容器中存储如图所示,Spring不仅会缓存单例对象,Bean定义也是会缓存的,对于惰性初始化的对象是在首次使用时根据Bean定义创建并存放于单例缓存池。

prototype即原型,指每次向Spring容器请求获取Bean都返回一个全新的Bean,相对于“singleton”来说就是不缓存Bean,每次都是一个根据Bean定义创建的全新Bean。

GoF原型设计模式,指用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

Spring中的原型和GoF中介绍的原型含义是不一样的:

GoF通过用原型实例指定创建对象的种类,而Spring容器用Bean定义指定创建对象的种类;

GoF通过拷贝这些原型创建新的对象,而Spring容器根据Bean定义创建新对象。

其相同地方都是根据某些东西创建新东西,而且GoF原型必须显示实现克隆操作,属于侵入式,而Spring容器只需配置即可,属于非侵入式。

Web应用中的作用域

在Web应用中,我们可能需要将数据存储到request、session、global session。因此Spring提供了三种Web作用域:request、session、globalSession。

一、request作用域:表示每个请求需要容器创建一个全新Bean比如提交表单的数据必须是对每次请求新建一个Bean来保持这些表单数据,请求结束释放这些数据。

二、session作用域:表示每个会话需要容器创建一个全新Bean比如对于每个用户一般会有一个会话,该用户的用户信息需要存储到会话中,此时可以将该Bean配置为web作用域。

三、globalSession类似于session作用域,只是其用于portlet环境的web应用。如果在非portlet环境将视为session作用域。

配置方式和基本的作用域相同,只是必须要有web环境支持,并配置相应的容器监听器或拦截器从而能应用这些作用域,我们会在集成web时讲解具体使用,大家只需要知道有这些作用域就可以了。

六、Spring之DI的Bean的作用域的更多相关文章

  1. Spring框架系列(三)--Bean的作用域和生命周期

    Bean的作用域 Spring应用中,对象实例都是在Container中,负责创建.装配.配置和管理生命周期(new到finalize()) Spring Container分为两种: 1.BeanF ...

  2. Spring系列四:Bean Scopes作用域

    等闲识得东风面,万紫千红总是春. 概述 在Spring框架中,我们可以在六个内置的spring bean作用域中创建bean,还可以定义bean范围.在这六个范围中,只有在使用支持Web的applic ...

  3. 8 -- 深入使用Spring -- 2...2 指定Bean的作用域

    8.2.2 指定Bean的作用域 当使用XML 配置方式来配置Bean实例时,可以通过scope来指定Bean实例的作用域,没有指定scope属性的Bean实例作用域默认是singleton. 当采用 ...

  4. java:Spring框架2(bean的作用域,静态工厂和实例工厂,自动装配,动态代理)

    1.bean的作用域,静态工厂和实例工厂: bean.xml: <?xml version="1.0" encoding="UTF-8"?> < ...

  5. Spring系列8:bean的作用域

    本文内容 bean定义信息的意义 介绍6种bean的作用域 bean定义信息的意义 Spring中区分下类.类定义信息,类实例对象的概念?不容易理解,以餐馆中点炒饭为例. 类: 相当于你看到菜单上炒饭 ...

  6. spring注解开发:bean的作用域与懒加载

    1.bean的作用域 1.新建一个maven工程,添加如下依赖 <dependency> <groupId>org.springframework</groupId> ...

  7. Spring学习记录(五)---bean的作用域scope

    作用域:singleton:单例,整个应用中只创建一个实例(默认) prototype:原型,每次注入时都新建一个实例 session:会话,每个会话创建一个实例 request:请求,每个请求创建一 ...

  8. JavaEE开发之Spring中Bean的作用域、Init和Destroy方法以及Spring-EL表达式

    上篇博客我们聊了<JavaEE开发之Spring中的依赖注入以及AOP>,本篇博客我们就来聊一下Spring框架中的Bean的作用域以及Bean的Init和Destroy方法,然后在聊一下 ...

  9. Spring 学习笔记 Bean的作用域

    在配置文件中定义Bean时,用户不但可以配置Bean的属性值以及相互之间的依赖关系,还可以定义Bean的作用域.作用域将对Bean的生命周期和创建方式产生影响.在低版本的Spring中,仅有两个作用域 ...

随机推荐

  1. [Objective-C语言教程]数字(13)

    在Objective-C编程语言中,要以对象形式保存基本数据类型,如:int,float,bool.Objective-C提供了一系列与NSNumber一起使用的方法,一些常用重要的方法列在下表中. ...

  2. Easyui里面动态设置输入框的可见性

    JQuery EasyUI 动态隐藏   一.隐藏datagrid某一列 $('#dg').datagrid('hideColumn', 'field'); 二.隐藏html的lable.input标 ...

  3. js实现抛物线

    这个是很简单的一种方式,利用了css3的transition属性 <!DOCTYPE html> <html lang="en" style="widt ...

  4. P2540 斗地主增强版

    P2540斗地主增强版 参考大佬题解 思路:顺子暴力搜,剩下的牌我不会贪心所以用记忆化搜索(或者dp): 注意:双王不能当对,二不算顺子 代码 #include <cstdio> #inc ...

  5. 从零开始完整搭建 Spring-Boot 项目开发框架的教程

    前言 难度:简单 类型:step-by-step 适用:初学者,完全没有接触过 Spring-Boot 开发环境:jdk 1.8 关键词:java, sring-boot, spring-mvc, r ...

  6. java FastJSON的使用

    1.JSON介绍 JSON(javaScript Object Notation)是一种轻量级的数据交换格式.主要采用键值对({"name": "json"}) ...

  7. 达人篇:3.1.3)FAI 首件检验

    本章目的:了解FAI. 1)定义: FAI: First Article Inspection Report . 汉语译作:首件全尺寸检验报告. 2)目的 制作FAI报告是为了检查成型后的产品尺寸是否 ...

  8. Linux下配置redis,c#简单调用

    redis比较流行的nosql库: 我这里测试本机window系统,虚拟机安装linux系统,linux系统部署redis,windwo系统,c#调用linux系统的redis 第一步:linux下安 ...

  9. MVC 和 MVR 的区别分析

    MVC模式中,可以将路由绑定到控制器上.MVR是一对一的.路由和控制器是一个东西. 优点是需要被迫处理路由.缺点是不能在控制器被绑定到路由之前复用控制器. [1] node.js - Differen ...

  10. maxscript批量设置摄像机并保存渲染图

    代码可直接运行 fn renderr = ( a=box() --新建一个立方体 ambientcolor = (color ) --设置环境光(搞不太懂,白的不出错就行) to do ( dis = ...