首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring_总结_04_高级配置(四)_bean的作用域

Spring_总结_04_高级配置(四)_bean的作用域

作者头像
shirayner
发布2018-09-20 10:51:34
3950
发布2018-09-20 10:51:34
举报
文章被收录于专栏:Java成神之路Java成神之路

一、前言

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-08-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
    • 1.单例bean
      • 2.有状态bean与无状态bean
      • 二、bean的作用域
        • 1.Prototype
          • 2.Session
            • 3.Request
            • 三、参考资料
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档