结论: 不是线程安全的
容器本身并没有提供Bean的线程安全策略,谈论Bean是否安全首先看一下它的作用范围:
Spring 的 bean 作用域(scope)类型
1、singleton:单例,默认作用域。
2、prototype:原型,每次创建一个新对象。
3、request:请求,每次Http请求创建一个新对象,适用于WebApplicationContext环境下,在请求完以后,bean会失效并被垃圾回收器回收。
4、session:会话,同一个会话共享一个实例,不同会话使用不用的实例,session过期,bean会失效。
5、global-session:全局会话,所有会话共享一个实例。
线程安全这个问题,要从单例与原型Bean分别进行说明。
1. 原型Bean
对于原型Bean,每次创建一个新对象,也就是线程之间并不存在Bean共享,自然是不会有线程安全的问题。
2. 单例Bean
对于单例Bean,所有线程都共享一个单例实例Bean,因此是存在资源的竞争。
但是,我们spring里面的bean大都是无共享变量的,专注于逻辑实现,此时又是线程安全的,这时候,资源竞争会体现在数据库层面。
变相问题:
@Controller @Service是不是线程安全的?
答:默认配置下不是的。为啥呢?因为默认情况下@Controller没有加上@Scope,没有加@Scope就是默认值singleton,单例的。意思就是系统只会初始化一次Controller容器,所以每次请求的都是同一个Controller容器,当然是非线程安全的。