Spring源码分析-启动流程浅析
Spring源码分析-BeanDefinition
Spring源码分析-Bean管理查找与注册(1)
Spring源码分析-Bean管理查找与注册(2)
Spring源码分析-Bean管理循环依赖和三级缓存
Spring源码分析-Bean生命周期概述
Spring源码分析-Bean生命周期createBean
由于bean的生命周期内容比较多,会分成多个博客进行分析,如果哪里介绍的不周,希望多多指出。
一个普通java对象生命周期基本就是:实例化 --> 属性赋值 --> 对象应用 --> gc回收 。这就是一个对象生命周期最基本的形态,在怎么扩展也不会跳出这圈的
那么4个阶段哪些阶段可以进行扩展呢?一一进行分析:
1)实例化,这个阶段是jvm操作,直接向操作系统申请内存,这个阶段是肯定不行的
2)销毁,这个阶段也是jvm操作,对象已经要销毁了就没有必要扩展了,但是在销毁前是可以做一些操作
3)对象应用,这个阶段已经在使用对象也没有必要扩展,但是在使用前是可以做一些操作
4)属性赋值,这个阶段前后都可以进行扩展,属性赋值前可操作性不大
实例化 --> 属性赋值 --> bean初始化过程 --> 对象应用 --> bean销毁过程 --> gc回收
注意:初始化和销毁,其实对应的就是init-method,destroy-method两个方法
然而spring并不止是这样的,还有更细化的流程,这个流程就需要有代码支撑
虽然spring进行生命周期的扩展,但仍然不足以满足业务需求,所以spring进行再次扩展后,再扩展后生命周期变为:实例化 -->属性赋值–> bean后置处理器的before方法 --> 属性后置处理afterPropertiesSet --> bean初始化过程 --> bean后置处理器的after方法 --> 对象应用 --> bean销毁过程 --> gc回收
bean的生命周期阶段很多,但是不要死记硬背,还是需要理解才能牢记于心。上面是我总结的整个过程,我认为是比较清晰的
一个普通类,没有任何注解标准,只实现了接口InitializingBean
public class Orders implements InitializingBean {
private String oname;
public Orders() {
System.out.println("第一步,执行Orders无参数构造");
}
public void setOname(String oname) {
this.oname = oname;
System.out.println("第二步,Set方法");
}
//接口InitializingBean的抽象方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("第四步,AfterProperties方法");
}
@PostConstruct
public void postConstruct() {
System.out.println("第三步, postConstruct --> BeanPostProcessor before方法");
}
@PreDestroy
public void preDestroy() {
System.out.println("第六步, preDestroy --> BeanPostProcessor before方法");
}
public void initMethod() {
System.out.println("第五步,initMethod方法");
}
public void destroyMethod() {
System.out.println("第七步,destroyMethod方法");
}
@Override
public String toString() {
return "Orders{" +
"oname='" + oname + '\'' +
'}';
}
}
//需要注册到spring容器中
public class MyBeanProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//这里根据bean类型,做一些特殊操作
/*
* if (bean instance XXX && beanName.startsWith("AAA")) {
* //进行增强处理
* return bean;
* } else {
* //do nothing
* return bean;
* }
*/
System.out.println("第三步,后置处理器前置方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第六步,后置处理器后置方法");
return bean;
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="order" class="com.worker.Orders" init-method="initMethod" destroy-method="destroyMethod">
<property name="oname" value="xuxb"/>
bean>
<bean id="myBeanProcessor" class="com.worker.MyBeanProcessor"/>
beans>
public static void main(String[] args) {
try {
GenericApplicationContext context = new AnnotationConfigApplicationContext("com.worker");
Orders order = context.getBean("myOrders", Orders.class);
System.out.println("对象应用----->");
System.out.println(order.toString());
System.out.println("<-----对象应用");
context.registerShutdownHook();
} catch (Exception e) {
System.out.println(e);
}
}
输出结果:
> Task :spring-study-01:WApp.main()
第一步,执行Orders无参数构造
第二步,Set方法
第三步,后置处理器前置方法
第四步,AfterProperties方法
第五步,initMethod方法
第六步,后置处理器后置方法
对象应用----->
Orders{oname='xuxb'}
<-----对象应用
第七步,destroyMethod方法
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
实现这个接口后,就可以对当前bean进行扩展,需要记住:只对当前bean有效
BeanPostProcessor也是一个接口,实现这个接口的类,必须作为组件Component注册到spring ioc容器中,才能对其他bean进行扩展,需要注意:该接口对所有的bean都生效
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
本篇博客,从原理和代码上,只说明了一个重点:bean的生命周期。这个知识点在面试中也会经常问到,希望能帮助大家