品牌型号:联想ThinkPad X1
系统:Windows10家庭版
软件版本:Spring 5.3.7
用过Spring的开发者对Bean肯定不陌生,如果问大家Bean有哪些作用域、它们之间有什么区别,估计有很多人说不清。我们平时写代码默认就是单例,也没出过什么问题,慢慢就没深究这块,但这个知识点在面试里出现的频率很高,实际开发里如果选错作用域可能会埋坑。下面就给大家介绍一下Spring Bean的作用域有哪些,Spring Bean的作用域之间有什么区别的相关内容。
一、Spring Bean的作用域有哪些
Spring一共提供了五种作用域,不过常用的就那么两三个,其余的只在特定环境下才会用到。例如singleton,也就是我们常说的单例,它是Spring的默认作用域,容器里只存一个实例,所有注入这个Bean的地方拿到的都是同一个对象。我们平时工作中绝大多数业务Bean用这个就够了,性能好、管理简单,只要Bean本身是无状态的,用起来基本没什么问题。

prototype多例,每次从容器里获取这个Bean,Spring都会新建一个实例。比较适合那些需要独立状态、不能共享的场景。要注意的是多例Bean的销毁Spring不管,用完了得我们开发者自己处理。

剩下的三种作用域都跟Web环境绑定,脱离了Web容器就用不了,像request作用域是每次HTTP请求创建一个新实例,请求结束实例销毁,同一次请求内共享同一个Bean。session作用域跟HTTP session绑定,同一个session内共享一个实例,session失效才销毁。application作用域是整个Web应用共享一个实例,跟singleton有点像,但它是挂在ServletContext上的,范围是整个Web应用而不只是Spring容器。

二、Spring Bean的作用域之间有什么区别
五种作用域看着多,但是作用域之间存在不少区别,在实例数量上,singleton全局只有一个,prototype每次都新建,request是单次请求范围内的单例,session是单个用户会话范围内的单例,application是整个Web应用范围内的单例。

生命周期上差异很大的是singleton和prototype,singleton从容器启动就创建,容器关闭才销毁,Spring全程管理它的生命周期,包括初始化回调和销毁回调都会触发。prototype则是用的时候创建,创建完Spring就不管了,销毁逻辑得我们自己处理。request和session的生命周期跟对应的HTTP请求和会话绑定,请求结束或者session失效,Bean随之销毁,Spring在Web环境下会自动处理这部分逻辑。application的生命周期跟Web应用一致,应用关闭才销毁。

然后就是singleton和prototype没有环境限制,普通的Spring应用和Web应用都能用。但request、session、application这三种必须在Web环境下才有效,非Web项目里声明这几种作用域会直接报错,这一点得注意。
还有一个实际开发中容易忽略的差异是singleton注入prototype的失效问题,单例Bean只初始化一次,如果里面注入了一个prototype的Bean,这个多例其实只会被创建一次,后续拿到的还是同一个实例,多例效果就失效了。这个坑不是作用域本身的问题,而是不同作用域混用时需要特别留意的地方,可以用@Lookup或者ObjectProvider等方式解决。

以上就是Spring Bean的作用域有哪些,Spring Bean的作用域之间有什么区别的全部内容了。Spring Bean的五种作用域有singleton和prototype,Web场景下有request和session还有application,singleton全程由Spring托管,prototype创建完就撒手不管,request和session跟Web生命周期绑定。