• 生命周期过程

主要分为四部分:

一、实例化

1. 当调用者通过 getBean( name )向 容器寻找Bean 时,如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,在实例 bean 之前,将调用该接口的 postProcessBeforeInstantiation ()方法。
2. 根据配置情况调用 Bean构造函数或工厂方法实例化 bean。
3. 如果容器注册了 org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,在实例 bean 之后,调用该接口的 postProcessAfterInstantiation ()方法,可以在这里对已经实例化的对象进行一些装饰。
4. 受用依赖注入,Spring 按照 Bean 定义信息配置 Bean 的所有属性 ,在设置每个属性之前将调用InstantiationAwareBeanPostProcess接口的 postProcessPropertyValues ()方法 。
5 .如果Bean实现了BeanNameAware接口,会回调该接口的setBeanName()方法,传入该Bean的id,此时该Bean就获得了自己在配置文件中的id。
6 .如果Bean实现了BeanFactoryAware接口,会回调该接口的setBeanFactory()方法,传入该Bean的BeanFactory,这样该Bean就获得了自己所在的BeanFactory。
7、如果Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()方法,传入该Bean的ApplicationContext,这样该Bean就获得了自己所在的ApplicationContext。

二、初始化

8.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()方法对 bean进行加工操作,这个非常重要, spring 的 AOP 就是用它实现的。

9.如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法,实现 InitializingBean接口必须实现afterPropertiesSet方法。(这个方法的作用是啥,还不太清楚)

10.如果Bean配置了init-method方法,则会执行init-method配置的方法。

11.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法。

三、执行具体的操作

12.经过流程9之后,就可以正式使用该Bean了,对于scope为singleton的Bean,Spring的ioc容器中会缓存一份该bean的实例,而对于scope为prototype的Bean,每次被调用都会new一个新的对象,期生命周期就交给调用方管理了,不再是Spring容器进行管理了。

然后就可以用这个Bean想干啥干啥了。。。

四、销毁

13.容器关闭后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法。

14.如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean的生命周期结束。

  • 代码解析

示例代码地址:https://github.com/handv/SpringMVCDemo/tree/master/SpringMVC_000

代码执行结果:

开始初始化容器
九月 25, 2016 10:44:50 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@b4aa453: startup date [Sun Sep 25 22:44:50 CST 2016]; root of context hierarchy
九月 25, 2016 10:44:50 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [com/test/spring/life/applicationContext.xml]
Person类构造方法
set方法被调用
setBeanName被调用,beanName:person1
setBeanFactory被调用,beanFactory
setApplicationContext被调用
postProcessBeforeInitialization被调用
afterPropertiesSet被调用
myInit被调用
postProcessAfterInitialization被调用
xml加载完毕
name is :jack
关闭容器
九月 25, 2016 10:44:51 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@b4aa453: startup date [Sun Sep 25 22:44:50 CST 2016]; root of context hierarchy
destory被调用
myDestroy被调用

1、AbstractAutowireCapableBeanFactory.populateBean

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
... if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//这里用到了InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//这里用到了postProcessAfterInstantiation方法
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
} ... boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//注册InstantiationAwareBeanPostProcessor接口
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//该处反射执行Bean的setxxx方法
applyPropertyValues(beanName, mbd, bw, pvs);
}

2、AbstractAutowireCapableBeanFactory.invokeAwareMethods()

private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
//设置BeanName
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
//设置BeanFactory
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

3、AbstractAutowireCapableBeanFactory.initializeBean

/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @return the initialized bean instance (potentially wrapped)
* @see BeanNameAware
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
*/
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
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, "Invocation of init method failed", ex);
} if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

后续代码可以看源码的注释,先不看了,太多了

参考:http://www.jianshu.com/p/3944792a5fff

最新文章

  1. MVC图片上传
  2. 最全面的 C++ 资源、框架大全
  3. jsp实现回车登录
  4. 使用VPN服务器解决公司不能上淘宝的问题
  5. C++中static用法总结
  6. Scala Error: error while loading Suite, Scala signature Suite has wrong version expected: 5.0 found: 4.1 in Suite.class
  7. Oracle中的阻塞锁SQL(阻塞在哪个数据上)
  8. 常用myeclipse的快捷键,对菜鸟超有用的
  9. 专访Facebook HipHop作者/阿里研究员赵海平:生物与计算机交织的独特人生
  10. HNOI2008玩具装箱
  11. JavaScript和JQuery的区别
  12. 解决VS2017不连接visual studio emulator for android
  13. 图解Tomcat类加载机制(阿里面试题)
  14. UVA10723 电子人的基因 Cyborg Genes
  15. [面试题]vi/vim快捷键及面试题系列
  16. bootstrap面试题
  17. 缩减apk大小
  18. 【CentOS 6.5】QtCreator启动时关于dbus-1的错误解决方法
  19. oracle日期格式转换 to_date()
  20. jsp:include 动作指令 与 include 指令

热门文章

  1. scala 官方教程
  2. JS的事件冒泡和事件捕获
  3. linux下mysql 启动命令
  4. Zookeeper安装和配置详解
  5. CSS3给页面打标签
  6. [redis] redis 对string类型数据操作
  7. Mike Gancarz:Linux/Unix设计思想
  8. JavaBean入门及简单的例子
  9. Servlet 工程 web.xml 中的 servlet 和 servlet-mapping 标签 《转载》
  10. Python的函数名作为参数传入调用以及map、reduce、filter