Spring 中 Bean 的生命周期

本文深入探讨Spring框架中Bean的生命周期,从实例化到销毁的全过程,包括依赖注入、Aware接口注入、BeanPostProcessor处理及InitializingBean接口的使用,帮助读者理解Bean在Spring中的管理机制。

在Java中,对于普通的Java对象,我们可以用new的方式、反射的方式、调用对象的clone方法或者运用反序列化手段去创建一个对象,当它没有任何引用的时会被垃圾回收机制回收。

而对于像由Spring IOC容器所托管的对象,它们的生命周期完全由容器所控制。接下来就来了解一下Bean在Spring中的生命周期。

一、Bean的生命周期

在这里插入图片描述

1. 实例化Bean

在这一阶段,Spring容器通过获取BeanDefinition对象中的信息进行实例化,这一步仅仅是简单的实例化,并未进行依赖注入。相当于我们程序中的new xx()

  • 对于BeanFactory容器,当客户向容器请求一个尚未初始化的Bean时,或初始化的时候需要注入另外一个尚未进行初始化操作的依赖时,容器就会调用createBean进行实例化;
  • 对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean。。

实例化对象被包装在BeanWrapper对象中(可以认为是Bean的原生态),BeanWrapper提供了对象属性的接口,避免了使用反射机制设置属性。

2. 设置对象属性

实例化后的对象被封装在BeanWrapper对象中,并且此时对象还是一个原生的状态,并没有进行依赖注入。

紧接着,Spring根据BeanDefinition中的信息进行依赖注入。并且通过BeanWrapper提供的设置属性的接口完成依赖注入。

3. 注入Aware接口

Aware接口用于增强Bean的能力。容器需要检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给bean。

常见的Aware接口有:BeanNameAwareBeanFactoryAwareApplicationContextAware。至此,一个对象已经被正确构造。

4. BeanPostProcess

结果上面几个步骤后,一个Bean对象就已经被正确地构造出来了,但是如果还想要对该对象进行一些自定义的处理,就可以通过BeanPostProcess接口实现。

该函数提供了两个函数:

  • postProcessBeforeInitialzation(Object bean, String beanName)

    当前正在初始化的bean对象会被传递进来,我们就可以对这个bean做一些处理。这个函数会先于InitialzationBean执行,因此称为前置处理。所有Aware接口的注入就是在在一步完成的。

  • postProcessAfterInitialzation(Object bean, String beanName)

    当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。这个函数会在InitialzationBean完成后执行,因此称为后置处理。

5. InitializingBean与init-method

当BeanPostProcessor的前置处理完成后就会进入本阶段。InitializingBean接口只有一个函数:

  • afterPropertiesSet()

    这一阶段也可以在bean正式构造完成前增加我们自定义的逻辑,但它与前置处理不同,由于该函数并不会把当前bean对象传进来,因此在这一步没办法处理对象本身,只能增加一些额外的逻辑。

    若要使用它,它们需要让bean实现该接口,并把要增加的逻辑写在该函数中。然后Spring会在前置处理完成后检测当前bean是否实现了该接口,并执行afterPropertiesSet()函数。

    当然,Spring为了降低对客户端代码的侵入性,给bean的配置提供了init-method属性,该属性指令了在这一阶段需要执行的函数名。Spring便会在初始化阶段需要执行的函数名。Spring便会在初始化阶段执行我们设置的函数。init-method本质上仍然使用InitalizingBean接口。

6. DisposableBean和destory-method

和init-method一样,通过给destroy-method指定函数,就可以在bean销毁前执行指定的逻辑。

二、相关类解析

1. 创建用于属性承载的 BeanDefinition

BeanDefinition是一个接口,在 Spring 中存在三种实现:RoorBeanDefinitionChildBeanDefinition以及GenericBeanDefinition。三种实现均继承了AbstractBeanDefinition,其中BeanDefinition是配置文件元素标签在容器中的内部表示形式。

元素标签拥有class、scope、lazy-init等配置属性,BeanDefinition则提供了相应的 beanClass、scope、lazyInit属性,BeanDefinition和中的属性是一一对应的。其中RootBeanDefinition是最常用的实现类,它对应一般相性的元素标签。

在配置文件中中可以定义父和子,父用RootBeanDefinition表示,而子用ChildBeanDefinition表示,而没有父的就使用RootBeanDefinition表示。

2. Aware

XXXAware在Spring中表示对XXX可以感知,通俗点解释就是:如果在某个类里面想要使用Spring的一些东西,就可以通过实现xxxAware接口告诉Spring,Spring看到后就会送过来,而接受的方式是通过实现接口唯一的方法setXXX。比如:ApplicationContextAware。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值