Spring bean 的生命周期很容易理解。实例化 bean 时,可能须要执行一些初始化以使其进入可用 (Ready for Use)状态。相似地,当再也不须要 bean 并将其从容器中移除时,可能须要进行一些清理,这就是它的生命周期java
上一篇文章 面试还不知道BeanFactory和ApplicationContext的区别? 中说明了接口 Beanfactory 和 Applicationcontext 能够经过 T getBean(String name, Class<T> requiredType)
方法从 Spring 容器中获取bean,区别是,前者是懒加载形式,后者是预加载的形式。那么问题来了:面试
这些 Spring Beans 是怎么生成出来的呢?spring
在正式回答这个问题以前,先解答一些有关 Java Bean, Spring Bean 和 Spring IoC 容器这些概念性的疑惑,我但愿经过下面这个例子形象说明这些问题:编程
小学生 (Java Bean)经过提交资料申请(元数据配置)加入了少先队(Spring Ioc 容器),学习了一些精神与规定以后,变成了少先队员(Spring Bean)设计模式
从这里能够看出,Java Bean 和 Spring Bean 都是具备特定功能的对象,小学生仍是那个小学生,只不过加入了少先队以后有了新的身份,新的身份要按照组织 (Spring Ioc)的规定履行特定义务网络
来看下图加深一下了解 框架
首先要有容器,实例化 Spring Ioc 容器是很是简单的,接口 org.springframework.context.ApplicationContext
表示Spring IoC容器,负责实例化,配置和组装上述 bean。 容器经过读取配置元数据获取有关要实例化,配置和组装的对象的指令。 配置元数据一般以XML,Java 注解或代码的形式表示。 它容许你本身表达组成应用程序的对象以及这些对象之间丰富的相互依赖性,好比这样:ide
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"spring.xml", "spring1.xml"});
有了容器,咱们须要作哪些处理,使其内部对象变为
Ready for Use
的状态?
咱们须要经过 Spring 容器实例化它们,Spring 为咱们提供了三种方式:post
Spring 为咱们提供了 InitializingBean
接口学习
public interface InitializingBean { void afterPropertiesSet() throws Exception; }
咱们能够经过实现 InitializingBean
接口,在其惟一方法 afterPropertiesSet
内完成实例化的工做,可是 Spring Framework 官方并不建议咱们经过这种方法来完成 Bean 的实例化,这是一种强耦合的方式,咱们看到框架层面才会用到这个方法。
这种方式是 Spring 很是提倡的一种方式,咱们一般将其标记在方法上便可,一般习惯将这个方法起名为 init()
@PostConstruct public void init() { System.out.println("Inside init() method..."); }
你应该见过这种初始化方式:
public class MyClass { public void init() { // perform post-creation logic here } } @Configuration public class AppConfig { @Bean(initMethod = "init") public MyClass myclass() { return new MyClass (); } }
你也应该见过这种配置方式:
<bean id="myClass" class="com.demo.MyClass" init-method="init"/>
没错,这只是一样功能的不一样实现方式罢了 以上就是三种初始化 Spring Beans 的方式,咱们在框架中看到过三种方式在组合使用,那么组合使用的调用顺序是什么呢?
InitializingBean.afterPropertiesSet()
方法将会被调用了解了这些,你也就了解了 Spring Bean 是怎么来的了
经过图示来讲明一下:
组合shying,这个调用顺序很难记忆吗吗?
PostConstruct
(P)
,afterPropertiesSet(A)
,init-method(I)
--->PAI (圆周率π)
BeanPostProcessor 接口,你们也应该有印象,里面只有两个方法:
public interface BeanPostProcessor { Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException; Object postProcessAfterInitialization(Object var1, String var2) throws BeansException; }
看方法名,BeforeInitialization 和 AfterInitialization,咱们应该猜得出,这是在上述三种方式的前和后,算是一种全局的切面思想,咱们常常会使用 postProcessAfterInitialization
方法,经过读取 Bean 的注解完成一些后续逻辑编写与属性的设定,如今 Ready for Use
以前是这样:
在 Ready for Use
以前,了解这些内容,已能够基本知足平常的工做内容,但这并非 Ready for Use 的所有内容,Spring Bean 整个生命周期的流程应该是这样的,后续文章会逐步点亮:
Ready for Use
以前有用处吗?XMLBeanFactory
这类方法,包括 XML 配置。这样作,只不过为了更清晰的说明问题。欢迎持续关注公众号:「日拱一兵」,后续会出一系列文章点亮 Spring Bean 周期图,以完整代码施力说明这个周期的顺序;同时进行 Spring 知识点解释与串联,轻松搞定面试那点事,以及在工做中充分利用 Spring 的特性