在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接口有:BeanNameAware、BeanFactoryAware、ApplicationContextAware。至此,一个对象已经被正确构造。
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 中存在三种实现:RoorBeanDefinition、ChildBeanDefinition以及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。
本文深入探讨Spring框架中Bean的生命周期,从实例化到销毁的全过程,包括依赖注入、Aware接口注入、BeanPostProcessor处理及InitializingBean接口的使用,帮助读者理解Bean在Spring中的管理机制。
1585

被折叠的 条评论
为什么被折叠?



