springIOC(上)

文章来源于微信公众号:三太子敖丙

IOC控制反转

类的创建、销毁都是由spring来控制,控制对象生存周期的不再是引用它的对象,而是由spring来控制整个过程。    


1、通过BeanDefinitionReader加载bean的配置信息,生成一个BeanDefinition(bean的定义信息,用来存储bean的所有属性方法定义)。

2、BeanFactoryPostProcessor接口是Spring初始化BeanFactory时对外暴露的扩展点,在bean实例化之前,获取bean的定义信息及修改相关信息。

3、BeanFactory是生产bean的工厂,他负责生产和管理各个bean实例,也是Spring容器暴露在外获取bean的入口;BeanFactory的生产过程其实是利用反射机制实现的。

Bean的生命周期

1、BeanNameAware#setBeanName:在创建此bean工厂中设置bean的名称,在普通属性设置之后调用的,在InitializingBean.afterPropertiesSet()方法之前调用。

2、BeanClassLoaderAware#setBeanClassLoader:将bean ClassLoader提供给bean实例的调用。

3、BeanFactoryAware#setBeanFactory:回调提供了自己的bean实例工厂,在普通属性设置之后,在InitializingBean.afterPropertiesSet()或者自定义初始化方法之前调用。

4、org.springframework.context.ResourceLoaderAware#setResourceLoader:在普通bean对象之后调用,在afterPropertiesSet 或者自定义的init-method 之前调用,在 ApplicationContextAware 之前调用。

5、org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher:在普通bean属性之后调用,在初始化调用afterPropertiesSet 或者自定义初始化方法之前调用。在 ApplicationContextAware 之前调用。

6、org.springframework.context.MessageSourceAware#setMessageSource:在普通bean属性之后调用,在初始化调用afterPropertiesSet 或者自定义初始化方法之前调用,在 ApplicationContextAware 之前调用。

7、org.springframework.context.ApplicationContextAware#setApplicationContext:在普通Bean对象生成之后调用,在InitializingBean.afterPropertiesSet之前调用或者用户自定义初始化方法之前。在ResourceLoaderAware.setResourceLoader,ApplicationEventPublisherAware.setApplicationEventPublisher,MessageSourceAware之后调用。

8、org.springframework.web.context.ServletContextAware#setServletContext:运行时设置ServletContext,在普通bean初始化后调用。

9、org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization:将此BeanPostProcessor 应用于给定的新bean实例。

10、InitializingBean#afterPropertiesSet:在设置所有 bean 属性后由包含的 BeanFactory调用。

11、org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName:获取InitMethodName名称,并且运行初始化方法。

12、org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization。

13、DisposableBean#destroy:销毁。

14、org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName:返回被销毁的bean名称。


public   void   refresh()   throws   BeansException, IllegalStateException{

   //   添加一个synchronized 防止出现refresh还没有完成出现其他的操作(启动,或者销毁) 

   synchronized (this.startupShutdownMonitor) {

      // 1.准备工作

      // 记录下容器的启动时间、

      // 标记“已启动”状态,关闭状态为false、

      // 加载当前系统属性到环境对象中

      // 准备一系列监听器以及事件集合对象

       prepareRefresh();

      // 2. 创建容器对象:DefaultListableBeanFactory,加载XML配置文件的属性到当前的工厂中(默认用命名空间来解析),就是上面说的BeanDefinition(bean的定义信息)这里还没有初始化,只是配置信息都提取出来了,(包含里面的value值其实都只是占位符)

      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 3. BeanFactory的准备工作,设置BeanFactory的类加载器,添加几个BeanPostProcessor,手动注册几个特殊的bean等

      prepareBeanFactory(beanFactory);

      try {

         // 4.子类的覆盖方法做额外的处理,就是我们刚开始说的 BeanFactoryPostProcessor ,具体的子类可以在这步的时候添加一些特殊的BeanFactoryPostProcessor完成对beanFactory修改或者扩展。

         // 到这里的时候,所有的Bean都加载、注册完成了,但是都还没有初始化

         postProcessBeanFactory(beanFactory);

         // 5.调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法

         invokeBeanFactoryPostProcessors(beanFactory);

         // 6.注册 BeanPostProcessor  处理器 这里只是注册功能,真正的调用的是getBean方法

        registerBeanPostProcessors(beanFactory);

         // 7.初始化当前 ApplicationContext 的 MessageSource,即国际化处理

         initMessageSource();

         // 8.初始化当前 ApplicationContext 的事件广播器,

         initApplicationEventMulticaster();

         // 9.从方法名就可以知道,典型的模板方法(钩子方法),感兴趣的同学还可以再去复习一下之前写的设计模式中的-模版方法模式

         //  具体的子类可以在这里初始化一些特殊的Bean(在初始化 singleton beans 之前)

         onRefresh();

         // 10.注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过

         registerListeners();

         // 11.初始化所有的 singleton beans(lazy-init 的除外),重点关注

         finishBeanFactoryInitialization(beanFactory);

         // 12.广播事件,ApplicationContext 初始化完成

         finishRefresh();

      }

      catch (BeansException ex) {

         if (logger.isWarnEnabled()) {

            logger.warn("Exception encountered during context initialization - " +

                  "cancelling refresh attempt: " + ex);

         }

         // 13.销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源

         destroyBeans();

         cancelRefresh(ex);

         // 把异常往外抛

         throw ex;

      }

      finally {

         // Reset common introspection caches in Spring's core, since we

         // might not ever need metadata for singleton beans anymore...

         resetCommonCaches();

      }

   }

}

常见面试题:

1、BeanFactory和ApplicationContext的区别?

    BeanFactory:是一个底层的IOC容器;

    ApplicationContext:在BeanFactory的基础上增加了一些他的特性的同时,又增加了一些其他的整合特性,比如:更好的整合了SpringAOP、国际化消息、事物的发布、资源访问等等。

2、BeanFactory 与 FactoryBean的区别?

    BeanFactory:是IOC底层容器。

    FactoryBean:是创建bean的一种方式,帮助实现复杂的初始化逻辑。

3、Spring IoC 容器的启动过程?(见ApplicationContext.refresh()方法中的内部13个子方法)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351