饿了么面试官:简历上说你精通Spring Bean的生命周期?

前言

Spring Bean的生命周期是Spring面试热点问题。这个问题即考察对Spring的微观了解,又考察对Spring的宏观认识,想要答好并不容易!本文但愿可以从源码角度入手,帮助面试者完全搞定Spring Bean的生命周期,如下部份内容参考Spring学习笔记,感兴趣的朋友也能够阅读一下!面试

SpringBean的生命周期

在面试中,咱们常常会被问到一个问题,就是SpringBean的生命周期。用大白话说,就是说其在创造到销毁按顺序调用了什么方法,在我刚开始学了,通常就是对着标准答案去硬背,彻底不了解其意思,也十分容易忘记。spring

流程图以下app

饿了么面试官:简历上说你精通Spring Bean的生命周期?

这样看上去十分的复杂,记住也很容易忘掉。ide

因此,我下面会用代码的方式一步步来模拟SpringBean的工做流程,作到深刻了解,这样就不会再次忘记这个知识点了。post

建立Bean对象

既然都说Bean对象Bean对象,那么SpringBean天然也是一个对象了,咱们用一个简单的对象来讲明,那么要建立对象就须要有构造方法,对象还会有它的属性跟get、set方法。学习

private String field;

 public SpringBean() {
 System.out.println("SpringBean 构造方法");
 }

 public String getField() {
 System.out.println("SpringBean get方法");
 return field;
 }

 public void setField(String field) {
 System.out.println("SpringBean set方法");
 this.field = field;
 }

众所周知要建立一个SpringBean的话还要在配置文件里去声明这个Beam,固然也能够用注解的方式。this

<bean class="SpringBean">
     <property name="field" value="test" />
 </bean>

而后咱们去初始化这个容器看看,运行结果是什么code

public static void main(String[] args) {
 ClassPathXmlApplicationContext applicationContext =
 new ClassPathXmlApplicationContext("spring.xml");
 }

饿了么面试官:简历上说你精通Spring Bean的生命周期?

这里咱们能够看到当咱们在容器里面加载bean的时候,它会依次调用构造方法和set方法,这两步我相信大部分人都知道。可是除此以外咱们想想,咱们的Spring它是否还干了别的事情,咱们接下来看一下。xml

重写setBeanName方法

若是这个Bean它实现了一些Aware接口的话,它就会注入和bean容器基础属性层面相关的信息。好比实现了BeanNameAware接口,咱们要重写它的setBeanName方法,在配置文件中把这个Bean的id设置一下对象

public void setBeanName(String s) {
 System.out.println("setBeanName:"+s);
 }
<bean id="BeanName" class="SpringBean">
     <property name="field" value="test" />
 </bean>

运行一下看会发生什么

饿了么面试官:简历上说你精通Spring Bean的生命周期?

剩下的BeanFactoryAware和ApplicationContextAware接口同理,咱们直接看结果

饿了么面试官:简历上说你精通Spring Bean的生命周期?

咱们能够看到先执行的是setBeanFactory方法而后是setApplicationContext方法

建立一个新的Bean

下面咱们再建立一个新的Bean,这个Bean是作全局的前置和后置初始化的,也就是咱们看面试题时所说的前置处理器和后置处理器。

这个Bean咱们实现BeanPostProcessor接口

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
 System.out.println("postProcessBeforeInitialization");
 return bean;
 }

 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
 System.out.println("postProcessAfterInitialization");
 return null;
 }

千万不要忘记要在配置文件里声明这个Bean

<bean class="SpringProccesserBean"></bean>

而后咱们再运行试试

饿了么面试官:简历上说你精通Spring Bean的生命周期?

不出咱们所料,前置方法和后置方法依次在后面运行了,难道这就是Bean的所有了吗?呵呵,太天真了,若是在Bean中有实现InitializingBean接口,那又是不一样的说法了。咱们下面除了重写了afterPropertiesSet方法之外咱们还能够在bean里面指定它的init方法。

public void afterPropertiesSet() throws Exception {
 System.out.println("afterPropertiesSet");
 }

 public void init(){
 System.out.println("init");
 }

不要忘记配置文件

<bean id="BeanName" class="SpringBean" init-method="init">
     <property name="field" value="test" />
 </bean>

饿了么面试官:简历上说你精通Spring Bean的生命周期?

能够看到,这两个方法是夹在前置处理器和后置处理器之间的,先执行的是InitializingBean接口的afterPropertiesSet方法而后是Bean自身的init方法。

至此,一个Bean的初始化环节就完成了,咱们就能够去使用这个Bean了。

既然是说Bean的生命周期,那固然还有Bean的销毁流程了,Bean的销毁流程一共分为连个步骤,一个步骤是实现销毁接口DisposableBean,重写它的销毁方法destroy,还有一个是Bean自身的destroy方法。

public void destroy() throws Exception {
 System.out.println("DisposableBean");
 }

public void des(){
 System.out.println("des");
 }

记得要在配置文件里定义

<bean id="BeanName" class="SpringBean" init-method="init" destroy-method="des">
     <property name="field" value="test" />
 </bean>

这两个方法会在关闭容易的时候调用,所以咱们调用close方法关闭容器

public static void main(String[] args) {
 ClassPathXmlApplicationContext applicationContext =
 new ClassPathXmlApplicationContext("spring.xml");

 applicationContext.close();

 }

运行结果

饿了么面试官:简历上说你精通Spring Bean的生命周期?

咱们看到是先调用DisposableBean接口的destroy方法而后是Bean自身的销毁方法。

这就是SpringBean的生命周期。

读者福利:Spring boot学习笔记+面试真题

总结

Spring Bean的生命周期

一、实例化Bean对象

二、设置Bean属性

三、若是经过各类Aware接口声明了依赖关系,则会注入Bean对容器基础设施层面的依赖。

Aware接口集体包括BeanNameAware、BeanFactoryAware和ApplicationContextAware

分别注入Bean ID、Bean Factory 和ApplicationContext

四、若是实现了BeanPostProcesser,调用BeanPostProcesser的前置初始化方法postProcessBeforeInitialization

五、若是实现了InitializingBean接口,则会调用afterPropertiesSet方法

六、调用Bean自身定义的init方法

七、调用BeanPostProcesser的后置方法postProcessAfterInitialization

建立完毕

销毁

八、容器关闭前调用DisposableBean的destroy方法和自身的destroy方法

相关文章
相关标签/搜索