Bean的生命周期

    在学习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的接口和相关依赖。

  1. BeanNameAware:注入当前 bean 对应 beanName;
  2. BeanClassLoaderAware:注入加载当前 bean 的 ClassLoader;
  3. BeanFactoryAware:注入 当前BeanFactory容器 的引用。

 

    在 invokInitMethods() 方法中会检查 InitializingBean 接口和 init-method 方法,销毁的过程也与其类似:

    在initializeBean()有两个BeanPostProcessors一个是一个是前置处理,一个是后置处理具体过程我们并不过多介绍。

初始化完成之后就是销毁了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秃啊顶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值