深入理解Spring:Bean

目录

1、Bean生命周期

2、Bean加载流程

2.1、容器启动阶段(Spring容器启动流程)

2.2、Bean的获取阶段

2.3、Bean的实例化阶段

3、Bean 作用域(scope)

4、Bean(Spring) 装配

4.1、bean装配方式

4.2、bean自动装配的几种方式

4.3、@Autowied和@Resource区别

5、Bean 延迟加载

6、Bean 依赖注入

7、BeanFactoryPostProcessor和BeanPostProcessor区别

7.1、BeanFactoryPostProcessor(修改配置)

7.2、BeanPostProcessor(实时处理)

8、BeanFactory和ApplicationContext区别

9、Bean 线程安全保障


1、Bean生命周期

可分8个阶段。实例化 ---->属性赋值---->初始化前---->初始化---->初始化后---->使用---->销毁前---->销毁。

(1)实例化

  • --对于BeanFactory容器(懒加载),用户请求一个未初始化bean时,容器会调用createBean进行实例化;
  • --对于ApplicationContext容器(预加载),容器启动结束后,自动获取BeanDefinition对象中的信息,实例化所有bean。

(2)属性赋值

Spring将 配置 或 注解 中定义的属性值赋值给Bean的响应属性。也叫设置对象属性和依赖注入(通过构造方法注入、setter方法注入等方式实现)。

(3)初始化前 回调(如有定义):属性赋值完成后Spring调用初始化前回调方法,如处理Aware接口,以便拿到Spring容器的资源

(4)初始化:如果Spring在配置文件配置了 init-method 属性,会自动调用它配置的初始化方法。

(5)初始化后 回调(如有定义):实现InitialzingBean接口,并实现afterPropertiesSet()方法。

(6)使用:初始化所有流程结束,Bean可以被使用,即可执行业务逻辑。

(7)销毁前 回调(如有定义):例如实现DisposableBean接口的destroy()方法

(8)销毁:在销毁前回调之后,Spring刚好执行额外的销毁操作,如调用Bean的destroy-method属性指定的销毁方法

2、Bean加载流程

Spring IoC像流水线上的机器,Bean像产品。既然要生产产品,机器要先运行。所以:

Bean的加载可分为2个阶段Spring容器启动阶段、Bean获取阶段

2.1、容器启动阶段(Spring容器启动流程)

:注意分清一个是bean加载流程一个是bean启动流程)

可以归纳为3个步骤:

(1)初始化Spring容器

加载配置元信息,通过BeanDefinitionReader读取器读取不同配置元信息,将这些元信息bean处理成Spring可以理解的BeanDefinition对象并注册到BeanDefinationRegistry。

(2)实例化bean对象

通过BeanFactory工厂,从BeanDefinationRegistry键值对拿到BeanDefinition,用来生成Bean对象(常用的实现类是XmlBeanFactory )

(3)注册bean后置处理器

通过BeanFactoryPostProcessor工厂获取的BeanPostProcessor后置处理器对bean增强或者修改
 

2.2、Bean的获取阶段

对象懒加载:直到对象实例化之前都是以BeanDefinationRegistry中的一个个的BeanDefination形式存在,Spring只有在第一次依赖对象的时候才开启实例化。

对象预加载:容器启动阶段完成后有一个步骤finishBeanFactoryInitialization()在这一步将立即启动Bean的实例化阶段,调用所有依赖对象getBean实例化所有配置的Bean,完成类的加载

(1)doGetBean()获取

在创建Bean对象之前先去缓存或者BeanFactory查看是否存在Bean, 存在则返回,不存在则进行创建爱Bean流程。

(2)getSingleton()从缓存获取单例Bean

Bean默认单例在容器中只会被创建一次,后续获取从单例缓存拿。单例缓存是公共变量,每次对他操作都要上锁。

(3)getObjectForBeanInstance()从Bean的实例中获取

2.3、Bean的实例化阶段

(1)加载类:通过类加载器,加载bean到内存。

(2)创建bean实例:类加载到内存后,JVM虚拟机通过有参或无参构造方法创建实例。

(3)分配内存:JVM为bean分配内存,内存可以装属性和方法

(4)属性赋值:初始化属性,包括使用默认值或者构造方法参数进行赋值

(5)执行构造方法:JVM调用构造方法进行额外的初始化操作,包括初始化依赖对象等

(6)返回实例:JVM返回已经实例化的bean对象

3、Bean 作用域(scope)

(1)singleton: 单例bean,每个容器只有一个bean实例(默认)-------线程不安全

(2)prototype: 为每一个bean请求创建一个实例 ------线程安全(线程之间不存在bean共享)

(3)request:为每一个request请求创建一个实例,请求结束bean失效且被垃圾回收

(4)session: 同一个session会话共享一个实例,不同会话使用不同实例

(5)global-session: 全局作用于,所有会话共享一个实例

4、Bean(Spring) 装配

指的是Spring框架中将组件bean组装在一起的过程

4.1、bean装配方式

(1)xml配置:xml配置文件使用<bean>定义bean

(2)注解配置:如@Component、@Service声明Bean,使用@Autowired进行自动装配

(3)java配置类:如@Configuration注解配置类,@Bean注解来定义Bean,并使用@Autowired进行自动装配

4.2、bean自动装配的几种方式

(1)byName自动装配:Spring会自动装配与属性名相同的Bean

(2)byType自动装配:Spring会自动装配与属性类型相同的Bean

(3)构造函数自动装配

(4)@Autowired、@Resource注解自动装配

4.3、@Autowied和@Resource区别

(1)来源不同:@Autowied由Spring提供,@Resource由SDK提供,如果不使用Spring框架只能用@Resource

(2)装配方式不同:@Autowied默认按type装配,@Resource默认按name装配

(3)装配顺序不同:@Autowied默认先按byType匹配,如果发现找到多个bean又按byName匹配,如果还有多个则抛出异常;@Resource默认byName查找,找不到再byType

(4)依赖注入支持不同(3种方式),@Autowied支持属性注入、构造方法注入、Setter注入。而@Resource只支持属性注入和Setter注入

5、Bean 延迟加载

指在Spring容器启动时不立即初始化Bean,而是在需要使用该Bean时才进行初始化。可使用@Lazy注解作用在类上,那这个类不会在Spring容器启动时立马加载,而是在用到时再初始化这个类bean到容器。

6、Bean 依赖注入

参考:深入理解Spring:AOP和IOC中-依赖注入的几种方式

7、BeanFactoryPostProcessor和BeanPostProcessor区别

7.1、BeanFactoryPostProcessor(修改配置)

在Spring容器加载Bean的定义后,在Bean实例化之前执行的。允许对Bean定义进行修改,如修改Bean的属性值等操作

7.2、BeanPostProcessor(实时处理)

在Spring容器实例化Bean之后,在Bean的初始化方法之前执行的。允许对Bean实例进行实时处理,如AOP代理的创建、事物管理、资源处理。

8、BeanFactory和ApplicationContext区别

(1)加载方式区别

BeanFactory是延时加载(懒加载)机制,容器启动时不会加载bean,要用时才加载并实例化,所以无法提前发现spring存在的配置问题;

ApplicationContext是容器启动时一次性加载所有bean。

(2)功能区别

BeanFactory是Spring中最底层的接口,是IOC的核心,其功能包含了各种Bean的定义、加载、实例化、依赖注入和生命周期的管理;

ApplicationContext接口是BeanFactory的子类,具有BeanFactory所有的功能,额外支持国际化、资源文件访问等。

9、Bean 线程安全保障

默认单例bean不是线程安全的(大多数据时候bean是无状态的如dao所以线程安全,有状态则必须手动保障线程安全了如自定义model实体)

(1)使用线程安全的数据结构

如ConcurrentHashMap

(2)避免共享状态

如果需要存储状态,可以使用ThreadLocal来保障每个线程拥有独立的状态

(3)使用同步机制

在需要保障线程安全的方法或代码块中,使用synchronized关或者ReentrantLock

(4)使用原子操作

(5)使用线程安全的作用域。如prototype

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值