Spring Bean的作用域

1. 常用的两种作用域

  Ø  scope="singleton"

  Ø  scope="prototype"

  首先,scope="singleton"是Spring的IoC容器创建Bean的默认作用域,它表示每个Bean只会创建一次,并将该Bean的状态进行保存,然后再次从IoC容器中拿同一个Bean时直接取用即可,不用再次创建。

  然后, scope="prototype"表示,每次从IoC容器中拿同一个Bean时都会全新地创建一个Bean,IoC容器不会保存Bean的状态。


2.  使用方法

  两种作用域的使用需遵照一定的原则,即:

  Ø  有状态的Bean采用scope="prototype"作用域,为了防止多线程下的线程安全问题。

  Ø  无状态的Bean采用默认的scope="singleton"的作用域,因为首先它不存在线程安全问题,其次,这样就可以共享实例,提高程序性能。

 具体一下:

  Ø  Struts2中的Action因为会有User、BizEntity这样的实例对象,是有状态信息的,在多线程环境下是不安全的。所以,在Spring中,Struts2的Action中,scope 要配成prototype作用域。

  Ø  而Service层、Dao层用默认singleton就行,虽然Service类也有dao这样的属性,但dao这些类都是没有状态信息的,也就是相当于不变(immutable)类,所以不影响。

  下面解释,“线程安全”与“有状态、无状态”的概念。


3.  线程安全

  当对一个复杂对象进行某种操作时,从操作开始到操作结束,被操作的对象往往会经历若干非法的中间状态。调用一个函数(假设该函数是正确的)操作某对象常常会使该对象暂时陷入不可用的状态(通常称为不稳定状态),等到操作完全结束,该对象才会重新回到完全可用的状态。如果其他线程企图访问一个处于不可用状态的对象,该对象将不能正确响应从而产生无法预料的结果。

  由以上可知,线程安全问题,是由于多个线程,同时操作某一个对象时可能引发的问题。也就是说,线程安全问题基本上都是由全局变量及静态变量引起的

  若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

  由此可知:

  Ø  常量始终是线程安全的,因为只存在读操作。

  Ø  每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源。

  Ø  局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量和方法内变量。


4.  有状态&无状态

       首先,我们经常用的Http协议是无状态的,浏览器请求完服务器就会立刻断开,不会一直连着服务器。服务器不会保存客户端的状态信息,所以为了保持Http连接状态才出现了Cookie和Session。而,有状态的协议中,比如UDP协议,从我们以前经常玩的CS游戏就可以看出,客户端与服务器是一直连着的,否则,如果连一下服务器就断开,等到再次连接上服务器,早就玩死了。

       个人感觉,一个对象的状态信息主要通过它的属性来体现。

  Ø  有状态就是有数据存储功能,可以保存数据,可以通过读写它的属性,来区分同一个类的两个不同的对象。它是非线程安全的。在不同方法调用间不保留任何状态。

  Ø  无状态就是一次操作,不能保存数据,是不变类,是线程安全的。

  Ø  总之,如果一个类的多个对象,可以区分开,那么就说是有状态的;反之,如果一个类的多个对象,是无法区分开的,那么就说是无状态的。

  一个Bean没有成员变量,或者那个Bean的成员变量也是无状态的Bean,那么这个Bean就是无状态的。通常这样的对象都是一些“操作”类,里面都是一些操作方法,例如,Service层、Dao层的类。反之就是有状态的Bean。


5.  总结

  scope="singleton"是Sping创建Bean的默认作用域,同一个id容器只存在一个共享的Bean实例。这样可以共享实例,提高性能。它适用于“无状态Bean”。而为了解决“有状态Bean”在多线程环境下的线程安全问题,出现的scope="prototype",它不共享实例,每次都会创建一个新的Bean。一般Service层、Dao层类都是无状态的,采用默认作用域即可,而Action一般是有状态的,所以需要设置scope="prototype"属性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值