什么是 Spring Bean?
Bean 代指那些被 IoC 容器所管理的对象。
什么是Spring IoC
IoC(Inversion of Control:控制反转) 是一种设计思想。IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理
- 控制:指的是对象实例化的权力
- 反转:控制权交给外部环境(Spring 框架、IoC 容器)
Spring中Bean管理方式
Bean管理指的是两个操作(依赖注入),分别为:
Spring创建对象(依赖)
Spring注入属性(注入)
Bean 管理有两种方式 :
基于xml配置文件方式实现
在XML配置文件中,使用bean标签,标签里面添加对应的属性,就可以实现对象的创建。如下所示:
<!-- 配置User对象 --> <bean id="user" class="com.wyf.spring5.User"></bean>
在Bean标签中有很多属性**,如上例中的id、class。常见的属性及其含义如下:
- id属性: 唯一标识(别名)
- class属性:类全路径(包类路径)
基于注解方式实现 @Component
:通用的注解,可标注任意类为Spring
组件@Repository
: 对应持久层即 Dao 层,主要用于数据库相关操作。@Service
: 对应服务层,主要涉及一些复杂的逻辑@Controller
: 对应控制层,主要用于接受用户请求并调用Service
层返回数据给前端页面
Bean 是线程安全的吗?
首先Spring框架中没有提供线程安全的策略。
Spring容器中的Bean都是根据自己写的类来创建的实例,Bean是否线程安全,与Spring容器无关
Bean 是否线程安全,取决于其作用域和状态。
作用域是什么:
在Spring定义的作用域中,有 prototype( 多例Bean )和 singleton ( 单例Bean)。多例的Bean,在每次 getBean 的时候都会创建一个新的对象。单例的Bean,在Spring容器中只会存在一个全局共享的实例。
由于多例Bean每次都会创建新实例,所以线程之间不存在Bean共享的问题。因此,多例Bean是线程安全的。
单例Bean是所有线程共享一个实例,因此,可能会存在线程安全问题。最后单例Bean又分为无状态Bean和有状态Bean。
有状态和无状态:在多线程操作中只会对Bean的成员变量进行查询操作,不会对Bean中的成员变量的数据进行操作,这样的Bean称之为无状态Bean。无状态的单例Bean是不存在线程安全问题的。在多线程操作中如果会对Bean中的成员变量的数据进行操作,这样的Bean称之为有状态Bean。有状态的单例Bean就可能存在线程安全问题。
大部分 Bean 实际都是无状态(没有定义可变的成员变量)的(比如 Dao、Service),这种情况下, Bean 是线程安全的。
如何解决Bean的线程安全问题
对于有状态单例 Bean 的线程安全问题,常见的有两种解决办法:
- 在 Bean 中尽量避免定义可变的成员变量。
- 在类中定义一个
ThreadLocal
成员变量,将需要的可变成员变量保存在ThreadLocal
中(推荐的一种方式)。
Bean 的生命周期
创建 Bean 的实例
Bean 属性赋值
Bean 初始化
销毁 Bean
@Component 和 @Bean 的区别是什么?
@Component
注解作用于类@Bean
注解作用于方法。