• 生命周期过程

主要分为四部分:

一、实例化

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

代码执行结果:

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

1、AbstractAutowireCapableBeanFactory.populateBean

  1. protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
  2. ...
  3. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  4. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  5. //这里用到了InstantiationAwareBeanPostProcessor
  6. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  7. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  8. //这里用到了postProcessAfterInstantiation方法
  9. if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
  10. continueWithPropertyPopulation = false;
  11. break;
  12. }
  13. }
  14. }
  15. }
  16. ...
  17. boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
  18. boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
  19. if (hasInstAwareBpps || needsDepCheck) {
  20. PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  21. if (hasInstAwareBpps) {
  22. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  23. //注册InstantiationAwareBeanPostProcessor接口
  24. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  25. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  26. //调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法
  27. pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
  28. if (pvs == null) {
  29. return;
  30. }
  31. }
  32. }
  33. }
  34. if (needsDepCheck) {
  35. checkDependencies(beanName, mbd, filteredPds, pvs);
  36. }
  37. }
  38. //该处反射执行Bean的setxxx方法
  39. applyPropertyValues(beanName, mbd, bw, pvs);
  40. }

2、AbstractAutowireCapableBeanFactory.invokeAwareMethods()

  1. private void invokeAwareMethods(final String beanName, final Object bean) {
  2. if (bean instanceof Aware) {
  3. if (bean instanceof BeanNameAware) {
  4. //设置BeanName
  5. ((BeanNameAware) bean).setBeanName(beanName);
  6. }
  7. if (bean instanceof BeanClassLoaderAware) {
  8. ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
  9. }
  10. if (bean instanceof BeanFactoryAware) {
  11. //设置BeanFactory
  12. ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
  13. }
  14. }
  15. }

3、AbstractAutowireCapableBeanFactory.initializeBean

  1. /**
  2. * Initialize the given bean instance, applying factory callbacks
  3. * as well as init methods and bean post processors.
  4. * <p>Called from {@link #createBean} for traditionally defined beans,
  5. * and from {@link #initializeBean} for existing bean instances.
  6. * @param beanName the bean name in the factory (for debugging purposes)
  7. * @param bean the new bean instance we may need to initialize
  8. * @param mbd the bean definition that the bean was created with
  9. * (can also be {@code null}, if given an existing bean instance)
  10. * @return the initialized bean instance (potentially wrapped)
  11. * @see BeanNameAware
  12. * @see BeanClassLoaderAware
  13. * @see BeanFactoryAware
  14. * @see #applyBeanPostProcessorsBeforeInitialization
  15. * @see #invokeInitMethods
  16. * @see #applyBeanPostProcessorsAfterInitialization
  17. */
  18. protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
  19. if (System.getSecurityManager() != null) {
  20. AccessController.doPrivileged(new PrivilegedAction<Object>() {
  21. @Override
  22. public Object run() {
  23. invokeAwareMethods(beanName, bean);
  24. return null;
  25. }
  26. }, getAccessControlContext());
  27. }
  28. else {
  29. invokeAwareMethods(beanName, bean);
  30. }
  31. Object wrappedBean = bean;
  32. if (mbd == null || !mbd.isSynthetic()) {
  33. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  34. }
  35. try {
  36. invokeInitMethods(beanName, wrappedBean, mbd);
  37. }
  38. catch (Throwable ex) {
  39. throw new BeanCreationException(
  40. (mbd != null ? mbd.getResourceDescription() : null),
  41. beanName, "Invocation of init method failed", ex);
  42. }
  43. if (mbd == null || !mbd.isSynthetic()) {
  44. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  45. }
  46. return wrappedBean;
  47. }

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

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

【spring mvc】application context中【bean】的生命周期的更多相关文章

  1. spring BeanFactory及ApplicationContext中Bean的生命周期

    spring bean 的生命周期 spring BeanFactory及ApplicationContext在读取配置文件后.实例化bean前后.设置bean的属性前后这些点都可以通过实现接口添加我 ...

  2. Spring学习-- IOC 容器中 bean 的生命周期

    Spring IOC 容器可以管理 bean 的生命周期 , Spring 允许在 bean 声明周期的特定点执行定制的任务. Spring IOC 容器对 bean 的生命周期进行管理的过程: 通过 ...

  3. Spring重点—— IOC 容器中 Bean 的生命周期

    一.理解 Bean 的生命周期,对学习 Spring 的整个运行流程有极大的帮助. 二.在 IOC 容器中,Bean 的生命周期由 Spring IOC 容器进行管理. 三.在没有添加后置处理器的情况 ...

  4. JAVA面试题:Spring中bean的生命周期

    Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一 ...

  5. 简:Spring中Bean的生命周期及代码示例

    (重要:spring bean的生命周期. spring的bean周期,装配.看过spring 源码吗?(把容器启动过程说了一遍,xml解析,bean装载,bean缓存等)) 完整的生命周期概述(牢记 ...

  6. Spring(十二):IOC容器中Bean的生命周期方法

    IOC容器中Bean的生命周期方法 1)Spring IOC容器可以管理Bean的声明周期,Spring允许在Bean生命周期的特定点执行定制的任务. 2)Spring IOC容器对Bean的生命周期 ...

  7. 7 -- Spring的基本用法 -- 9...容器中Bean的生命周期

    7.9 容器中Bean的生命周期 Spring可以管理singleton作用域的Bean的生命周期,Spring可以精确地知道该Bean何时被创建,何时被初始化完成.容器何时准备销毁该Bean实例. ...

  8. 一分钟掌握Spring中bean的生命周期!

    Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean 的别名只能维持 ...

  9. Spring中bean的生命周期!

    Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一 ...

  10. Spring中 bean的生命周期

    为什么要了解Spring中 bean的生命周期? 有时候我们需要自定义bean的创建过程,因此了解Spring中 bean的生命周期非常重要. 二话不说先上图: 在谈具体流程之前先看看Spring官方 ...

随机推荐

  1. struts2 + spring3 + mybatis3 环境搭建

    struts2 + spring3 + mybatis3 1. 框架下载 struts2: http://struts.apache.org/ 下载 struts-2.3.14-all.zip spr ...

  2. Unity获取指定资源目录下的所有文件

    使用前需要引入System.IO;这个命名空间 public void GetFiles() { //路径 //string path = string.Format("{0}", ...

  3. 我的javascript心跳机

    li { list-style: none!important; padding:0; } .list_num{ list-style-type:decimal; } .list_inline{ ma ...

  4. Python urllib2 模块

    urllib2.urlopen(url, data=None, timeout=<object object>) :用于打开一个URL,URL可以是一个字符串也可以是一个请求对象,data ...

  5. Serlvet学习笔记之四—对文件的操作

    1.读文件 package com.demo; import java.io.BufferedReader; import java.io.FileReader; import java.io.Pri ...

  6. React如何进行事件传参

    今天在学习React的es6语法的时候,发现了个有趣的现象,就是this的指向问题.es6的this不同于es5,它在创立函数伊始便已经存在了,而不是像es5一样,睡调用的函数,this指向谁.但是这 ...

  7. 通过WireShark抓取iOS联网数据实例分析

    本文转载至http://blog.csdn.net/lixing333/article/details/7782539 iosiphone网络filter工具 我在另外一篇博客里,介绍了一款比Wire ...

  8. Oracle里 用sql*plus 登陆时,用户名和密码是多少啊?

    Oracle里sql*plus的用户名即system用户,密码是自己设置的密码. 如果密码忘记,可通过如下方法重置. 1.win键+R键,输入cmd,打开命令提示符. 2.输入sqlplus /nol ...

  9. Windows下Mysql主从配置(Mysql5.5)

    主数据库IP:192.168.3.169从数据库IP:192.168.3.34 主数据库配置my.inin: 在[mysqld]下添加配置数据:server-id=1     #配一个唯一的ID编号, ...

  10. 关于Ethread的一些研究

    环境 win764 以TP为例 ring3保护 它会在windbg断下 这个时候我们需要拿到当前线程对象 应该到 当前使用的CPU的地址 _KPRCB-> CurrentThread 就是当前线 ...