在学习Bean的生命周期前,我们要先了解,生命周期是什么,简单来讲Bean的生命周期就是Bean从创建到销毁的整个过程就叫做Bean的生命周期。
Bean的生命周期分为五个阶段他们分别为:实例化,属性注入,初始化,使用Bean和销毁Bean。
其中初始化其中有多个步骤也是其中最复杂的步骤,这一阶段包含了各种通知 BeanNameAware , BeanFactoryAware ,ApplicationContextAware 的接⼝⽅法.以及执行的初始化方法 xml定义 init-method,使⽤注解的⽅式 @PostConstruct,执⾏初始化后置⽅法( BeanPostProcessor )。
销毁容器也有各种方法, 如 @PreDestroy , DisposableBean 接⼝⽅法, destroy-method.
由于Bean生命周期是面试经常考察的知识点之一,因此在这里我们会配合源码比较详细的讲解Bean的生命周期。
其中第一阶段的实例化只是为Bean提供了内存空间而已,并没有进行其他的操作。我们在这里使用,“先使用后理解”的方式直观地让搭建感受一下Bean生命周期的整个过程。
首先随便创建一个类:
@Configuration @Setter @Getter public class Dog { private int age; private String name; }
随后进行模拟Bean生命周期的整个过程:
@Component //初始化阶段的通知
public class BeanLifeComponent implements BeanNameAware {
private Dog dog;
public BeanLifeComponent() {
System.out.println("执行构造函数...");
}
@Autowired
public void setDog(Dog dog) {this.dog = dog;}
@PostConstruct //执行初始化方法
public void init(){
System.out.println("执行init方法...");
}
@Override //初始化阶段的通知重写
public void setBeanName(String name) {
System.out.println("执行setBeanName, name:"+name);
}
public void use(){System.out.println("执行use方法....");}
@PreDestroy //bean的销毁
public void destroy(){
System.out.println("执行destroy方法...");
}
}
下面是他们的运行结果:
此时我们会发现当程序并没有结束的时候,销毁方法并没有执行,接下来我们结束程序 :
我们可以看到销毁方法执行了,在这里我们就简单的模拟了一下Bean的生命周期,接下来我们来详细的讲解一下这个过程。
如果我们想要详细的观察这个过程我们必须要去找到Bean的创建路口也就是创建Bean的代码⼊⼝: AbstractAutowireCapableBeanFactory#createBean
其中有许多我们不需要的方法,我们直接省略,我们只去找我们所需要的也就是:createBean:
由于源码过长我们只取其中关乎生命周期重要的点:
其中有一个doCreateBean()方法我们点进去,点进去之后我们可以看到这段代码也是比价长的,在这个方法中有三部分比较重要分别是:1.createBeanInstance() -> 实例化
2. populateBean() -> 属性赋值,3. initializeBean() -> 初始化。
实例化和属性赋值大家了解就好,接下来进入initializeBean()方法内:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
这个方法包含的信息比较多,我们其中 invokeAwareMethods()内部就包含了我们所提到的各种通知,此处是为了检查aware的接口和相关依赖。
- BeanNameAware:注入当前 bean 对应 beanName;
- BeanClassLoaderAware:注入加载当前 bean 的 ClassLoader;
- BeanFactoryAware:注入 当前BeanFactory容器 的引用。
在 invokInitMethods() 方法中会检查 InitializingBean 接口和 init-method 方法,销毁的过程也与其类似:
在initializeBean()有两个BeanPostProcessors一个是一个是前置处理,一个是后置处理具体过程我们并不过多介绍。
初始化完成之后就是销毁了。