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个子方法)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。