Spring中Bean的安全性问题--面试题

Spring中Bean的安全性

  • Spring中的Bean从何而来?
  • Spring中什么样的Bean存在线程安全问题?
  • 如何处理spring Bean的线程安全问题?

Spring中的Bean从何而来?

Spring中除了很多内置Bean以外,其他的Bean都是通过Spring配置来声明的,然后由Spring容器统一加载。Spring声明配置时会配置以下内容。如:class(全类名)、id(Bean的唯一标识)、Scope(作用域),之后Spring容器根据配置内容使用对应的策略来创建Bean的实例。
因此,Spring 容器中的 Bean 其实都是根据我们自己写的类来创建的实例。所以, Spring 中的 Bean 是否线程安全,跟 Spring 容器无关,只是交由 Spring 容器托管而已。

Spring中什么样的Bean存在线程安全问题?

Spring框架里的bean,在获取实例的时候都是默认的单例模式
在 Spring 定义的作用域中,其中有 prototype(多例 Bean)和 singleton(单例 Bean)。

  1. 定义为 prototype 的 Bean,是在每次 getBean 的时候都会创建一个新的对象。
  2. 定义为 singleton 的 Bean,在 Spring 容器中只会存在一个全局共享的实例。

多例 Bean 每次都会新创建新实例,也就是说线程之间不存在 Bean 共享的问题。因此,多例 Bean 是不存在线程安全问题的。而单例Bean 是所有线程共享的一个实例,因此,就可能会存在线程安全问题。

单例 Bean 又分为无状态 Bean 和有状态 Bean 。

  1. 无状态Bean:在多线程操作中只会对 Bean 的成员变量进行查询操作,不会修改成员变量的值,这样的 Bean称之为无状态 Bean 。所以,可想而知,无状态的单例 Bean 是不存在线程安全问题的。
  2. 有状态 Bean :但是在多线程操作中如果需要对 Bean 中的成员变量进行数据更新操作,这样的 Bean 称之为有状态 Bean ,所以,有状态的单例 Bean 就可能存在线程安全问题

如何处理spring Bean的线程安全问题?

处理有状态的 Bean 的线程安全问题有以下三种方法:

  1. 将 Bean 的作用域由“singleton”单例改为“prototype”多例 在 Bean
  2. 对象中避免定义可变的成员变量
  3. 在类中定义 Thread Local的成员变量,并将需要的可变成员便来给你保存在 Thread Local 中,Thread Local 本身就具备线程隔离的特性,这就相当于为每个线程提供了一个独立的变量副本,每个线程只需要操作自己的线程副本变量,从而解决线程安全问题
    如果大家想详细了解一下ThreadLocal可以看一下这个 ThreadLocal保证线程安全-面试题

你可能感兴趣的:(面试题,spring,Java,spring,java,后端)