一、前言

本文承接上一节: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 实战 (第四版)》

Spring_总结_04_高级配置(四)_bean的作用域的更多相关文章

  1. Spring_总结_04_高级配置(六)_Bean的初始化和销毁

    一.前言 本文承接上一节:Spring_总结_04_高级配置(五)_运行时注入值

  2. Spring_总结_04_高级配置(五)_运行时注入值

    一.前言 本文承接上一节:Spring_总结_04_高级配置(四)_bean的作用域 当讨论依赖注入的时候,我们通常所讨论的是将一个bean引用注入到另一个bean的属性或者构造参数中.它通常指的是将 ...

  3. Spring_总结_04_高级配置(三)_处理歧义

    一.前言 本文承接上一节:Spring_总结_04_高级配置(二)之条件注解@Conditional 我们前面装配bean时,在Spring容器中,都是只有一个bean能匹配所需的结果. 如果有多个b ...

  4. Spring_总结_04_高级配置(二)_条件注解@Conditional

    一.前言 本文承接上一节:Spring_总结_04_高级配置(一)之Profile 在上一节,我们了解到 Profile 为不同环境下使用不同的配置提供了支持,那么Profile到底是如何实现的呢?其 ...

  5. Spring_总结_04_高级配置(一)_Profile

    一.前言 本文承接上一节:Spring_总结_03_装配Bean(四)之导入与混合配置 这一节,来总结一下profile. 我们在开发软件时,通常会进行跨环境部署.而在跨环境部署时,经常会遇到某些环境 ...

  6. Cisco ASA 高级配置

    Cisco ASA 高级配置 一.防范IP分片攻击 1.Ip分片的原理: 2.Ip分片的安全问题: 3.防范Ip分片. 这三个问题在之前已经详细介绍过了,在此就不多介绍了.详细介绍请查看上一篇文章:I ...

  7. Stm32高级定时器(四)

    Stm32高级定时器(四) 1 编码器接口模式 1.1 编码器原理 什么是正交?如果两个信号相位相差90度,则这两个信号称为正交.由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向.根 ...

  8. Spring_总结_03_装配Bean(四)_导入与混合配置

    一.前言 本文承接上一节:Spring_总结_03_装配Bean(三)之XML配置 在典型的Spring应用中,我们可能会同时使用自动化和显示配置.同时,可能在某些场景下我们需要混合使用JavaCon ...

  9. Nginx 高级配置-https 功能

    Nginx 高级配置-https 功能 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.HTTPS工作过程 1>.SSL/TLS SSL(Secure Socket Lay ...

随机推荐

  1. Android测试读写sd卡文件与写sd卡文件耗时

    测试从sd卡读1k大小的文件,再写1k大小的文件,由于处理耗时很短,所以循环500次,查看耗时:测试写1k大小的文件,直接在内存构造一个1k的buffer,将这个buffer直接写到文件,同样循环50 ...

  2. Redis3.2.8配置参数及说明

    bind 127.0.0.1# 绑定的主机地址,不设置默认将处理所有请求protected-mode yes# 是否开启保护模式,默认开启,要是配置里面没有指定bind和密码,开启该参数后,redis ...

  3. 【C语言】linux C写入本地文件

    //定义写入文件 FILE *pFile; //定义文件路径变量 ]; //变量赋值 sprintf(local_file,"/tmp/test.json"); //打开文件 pF ...

  4. Python之正则表达式与常用模块(Day19)

    一.正则表达式:匹配字符串的一种规则 正则表达式的在线测试工具: http://tool.chinaz.com/regex/ 字符组: 正则 待匹配字符 匹配结果 说明 [0123456789] 8 ...

  5. 前端基础之JavaScript_(1)_ECMAScript

    一.JavaScript概述 JavaScript的历史 992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase. ...

  6. PAT 天梯赛 L1-020. 帅到没朋友 【STL】

    题目链接 https://www.patest.cn/contests/gplt/L1-020 思路 对于每个 K >= 2 的朋友圈,里面的所有 ID 都用 MAP 标记一下 对于每个 K = ...

  7. $git学习总结系列(2)——远程仓库

    本文主要介绍git本地仓库和GitHub远程仓库之间的交互和数据传输. 注:首先需要到github.com上注册一个账号. 1. 添加本地SSH Key到GitHub 要向GitHub远程仓库推送代码 ...

  8. python tkinter组件学习

    http://blog.csdn.net/pfm685757/article/details/50162567

  9. yii框架模型操作

    命令行自动生成model模型类 php yii gii/model --ns=app\\modules\\v1\\models --tableName=SCM_tbInvBalance_new --m ...

  10. python__Django 分页

    自定义分页的类: #!/usr/bin/env python # -*- coding: utf-8 -*- # Created by Mona on 2017/9/20 from django.ut ...