Spring Bean 的生命周期,面试时非常容易问,这不,前段时间就有个读者去面试,因为不会回答这个问题,一面都没有过。
如果只讲基础知识,感觉和网上大多数文章没有区别,但是我又想写得稍微深入一点。
考虑很多同学不喜欢看源码,我就把文章分为 2 大部分,前面是基础知识,主要方便大家面试和学习,后面是源码部分,对源码感兴趣的同学可以继续往后面看。
不 BB,上文章目录。
1. 基础知识
1.1 什么是 IoC ?
IoC,控制反转,想必大家都知道,所谓的控制反转,就是把 new 对象的权利交给容器,所有的对象都被容器控制,这就叫所谓的控制反转。
IoC 很好地体现了面向对象设计法则之一 —— 好莱坞法则:“别找我们,我们找你”,即由 IoC 容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
理解好 IoC 的关键是要明确 “谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”。
谁控制谁,控制什么?
传统 Java SE 程序设计,我们直接在对象内部通过 new 进行创建对象,是程序主动去创建依赖对象。而 IoC 是由专门一个容器来创建这些对象,即由 IoC 容器来控制对象的创建。
-
谁控制谁?当然是 IoC 容器控制了对象;
-
控制什么?主要控制了外部资源获取(不只是对象,比如包括文件等)。
为何是反转,哪些方面反转了?
有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转,而反转则是由容器来帮忙创建及注入依赖对象。
-
为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;
-
哪些方面反转了?依赖对象的获取被反转了。
1.2 Bean 生命周期
对 Prototype Bean 来说,当用户 getBean 获得 Prototype Bean 的实例后,IOC 容器就不再对当前实例进行管理,而是把管理权交由用户,此后再 getBean 生成的是新的实例。
所以我们描述 Bean 的生命周期,都是指的 Singleton Bean。
Bean 生命周期过程:
-
实例化:第 1 步,实例化一个 Bean 对象;
-
属性赋值:第 2 步,为 Bean 设置相关属性和依赖;
-
初始化:初始化的阶段的步骤比较多,5、6 步是真正的初始化,第 3、4 步为在初始化前执行,第 7 步在初始化后执行,初始化完成之后,Bean 就可以被使用了;
-
销毁:第 8~10 步,第 8 步其实也可以算到销毁阶段,但不是真正意义上的销毁,而是先在使用前注册了销毁的相关调用接口,为了后面第 9、10 步真正销毁 Bean 时再执行相应的方法。
整个执行流程稍微有些抽象,下面我们通过代码,来演示执行流程。
1.3 执行流程
创建一个 LouzaiBean。
public class LouzaiBean implements InitializingBean, BeanFactoryAware, BeanNameAware, DisposableBean {
/**
* 姓名
*/
private String name;
public LouzaiBean() {
System.out.println("1.调用构造方法:我出生了!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("2.设置属性:我的名字叫"+name);
}
@Override
public void setBeanName(String s) {
System.out.println("3.调用BeanNameAware#setBeanName方法:我要上学了,起了个学名");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("4.调用BeanFactoryAware#setBeanFactory方法:选好学校了");
}
@Override
public void afterPropertiesSet() throw