美文网首页spring专题
Spring IOC ApplicationContext 源码

Spring IOC ApplicationContext 源码

作者: Kohler | 来源:发表于2018-08-17 23:19 被阅读94次

    作为Spring提供的较之 BeanFactory 更为先进的IoC容器实现, ApplicationContext 除了拥有BeanFactory 支持的所有功能之外,还进一步扩展了基本容器的功能,包括 BeanFactoryPostProcessor 、 BeanPostProcessor 以及其他特殊类型bean的自动识别、容器启动后bean实例的自动初始化、国际化的信息支持、容器内事件发布等。

    ApplicationContext 继承结构

    image

    ApplicationContext 的继承机构可以看到, ApplicationContext 继承了BeanFactory,也就是说,ApplicationContext 拥有BeanFactory的全部功能,ApplicationContext 是通过将容器的功能委派给DefaultListableBeanFactory来实现。除了继承BeanFactory,还有ResourceLoaderEnvironmentCapableApplicationEventPublisherMessageSource等接口,也就说明ApplicationContext 除了容器的功能外,还囊括了资源的处理、环境、事件发布、国际化等。

    ApplicationContext 源码

    创建一个常用的ApplicationContext

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
    

    ApplicationContext 初始化

    ClassPathXmlApplicationContext的构造函数在设置完配置文件的位置后,紧接着调用refresh()方法。refresh方法是加载或刷新配置的信息,同时加载容器的单例。

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 为刷新准备这个context。
            prepareRefresh();
    
            // 告诉子类刷新内部bean工厂。
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
            // 准备好bean工厂,以便在此context中使用。
            prepareBeanFactory(beanFactory);
    
            try {
                // 允许在context子类中对BeanFactory进行post-processing。
                postProcessBeanFactory(beanFactory);
    
                // 调用在context中注册为bean的工厂处理器(BeanFactoryPostProcessor)。
                invokeBeanFactoryPostProcessors(beanFactory);
    
                // 注册拦截bean创建的BeanProcessor。
                registerBeanPostProcessors(beanFactory);
    
                // 为context初始化消息源。
                initMessageSource();
    
                // 为context初始化事件多播。
                initApplicationEventMulticaster();
    
                // 初始化子类context中的其他特殊bean。
                onRefresh();
    
                // 检查listener类型的bean并注册它们。
                registerListeners();
    
                // 实例化所有剩余的(non-lazy-init)单例。
                finishBeanFactoryInitialization(beanFactory);
    
                // 最后一步:发布相应的事件。
                finishRefresh();
            }
    
            catch (BeansException ex) {
                ...
            }
    
            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }
    

    obtainFreshBeanFactory

    obtainFreshBeanFactory()方法核心是内部调用refreshBeanFactory()方法并将容器内部的ConfigurableListableBeanFactory返回,从这也看到了ApplicationContext和BeanFactory的关系:ApplicationContext内部包含一个BeanFactory,ApplicationContext所有关于BeanFactory的功能将委派给此BeanFactory处理。

    AbstractRefreshableApplicationContext#refreshBeanFactory源码:

    protected final void refreshBeanFactory() throws BeansException {
       // 清理之前的BeanFactory
       if (hasBeanFactory()) {
          destroyBeans();
          closeBeanFactory();
       }
       try {
          // createBeanFactory方法直接新建一个DefaultListableBeanFactory,也就是说内部使用的是DefaultListableBeanFactory实例
          DefaultListableBeanFactory beanFactory = createBeanFactory();
          beanFactory.setSerializationId(getId());
          // 自定义此上下文使用的内部bean工厂
          customizeBeanFactory(beanFactory);
          // 将BeanDefinition加载到给定的bean工厂中,通常通过委托给一个或多个BeanDefinitionReader来实现
          // 子类实现的方法,此处调用的是AbstractXmlApplicationContext的方法
          loadBeanDefinitions(beanFactory);
          synchronized (this.beanFactoryMonitor) {
             this.beanFactory = beanFactory;
          }
       }
       catch (IOException ex) {
          throw new ApplicationContextException(...);
       }
    }
    

    也就是说这一步是构建ApplicationContext内部的BeanFactory,以及根据配置将BeanDefinition加载到BeanFactory中。

    prepareBeanFactory

    配置工厂的标准上下文特征,比如上下文的类加载器和后处理器。

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       // 告诉内部bean工厂使用上下文的ClassLoader等。
       beanFactory.setBeanClassLoader(getClassLoader());
       // 使用Spring的表达式模块解析和计算Spring EL表达式
       beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
       // 属性编辑器
       beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
       // 这个在BeanFactory源码提到过的,扩展的Aware类型通过BeanPostProcessor来装配
       beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
       beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
       beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
       beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
       beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    
       // 注册为可装配的依赖,而不是bean
       // MessageSource注册为bean
       beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
       beanFactory.registerResolvableDependency(ResourceLoader.class, this);
       beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
       beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
       // 注册early post-processor检测bean是否为applicationlistener。
       beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
       // 检测LoadTimeWeaver并为织入做准备
       if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
          beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
          // 为类型匹配设置一个临时类加载器。
          beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
       }
    
       // 注册默认的环境beans
       if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
          beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
       }
       if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
          beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
       }
       if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
          beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
       }
    }
    

    postProcessBeanFactory

    对BeanFactory预处理,ClassPathXmlApplicationContext未重写,WebXmlApplicationContext有重写,这里不展开。

    invokeBeanFactoryPostProcessors

    在任何应用程序bean的实例化之前,实例化并调用所有已注册的BeanFactoryPostProcessor bean,如果实现了PriorityOrdered或者Ordered接口这按顺序调用。

    invokeBeanFactoryPostProcessors方法主要有两个调用:

    1. invokeBeanFactoryPostProcessors,调用BeanFactoryPostProcessors
    2. 检测LoadTimeWeaver,选择添加LoadTimeWeaverAwareProcessor,这一步在prepareBeanFactory已经做了

    invokeBeanFactoryPostProcessors方法逻辑很简单

    1. 如果beanFactory是BeanDefinitionRegistry,则先处理BeanDefinitionRegistryPostProcessor
    2. 处理完ApplicationContext的BeanDefinitionRegistryPostProcessor后,实例化beanFactory的BeanDefinitionRegistryPostProcessor,按照PriorityOrdered -> Ordered -> non,顺序处理
    3. 按照BeanFactoryPostProcessor的方法,处理以上所有的,包括BeanDefinitionRegistryPostProcessor
    4. 还没完,第二步是取出beanFactory的BeanDefinitionRegistryPostProcessor,还有部分它的超类BeanFactoryPostProcessor未处理。按照2、3步处理未执行的BeanFactoryPostProcessor

    registerBeanPostProcessors

    在任何应用程序bean的实例化之前,按照顺序,实例化并调用所有已注册的BeanPostProcessor bean。

    注册BeanPostProcessor和注册BeanFactoryPostProcessor类似,主要步骤

    1. 注册BeanPostProcessorChecker,当bean在BeanPostProcessor实例化过程中创建时,它记录一个信息消息
    2. 从beanFactory中取出按照BeanPostProcessor类型取出postProcessorNames,然后实例化,按照PriorityOrdered -> Ordered -> non的顺序依次注册到beanFactory
    3. 注册一个ApplicationListenerDetector用于检测实例化的bean是否为一个ApplicationListeners,是则注册listener

    initMessageSource

    MessageSource用于处理I18n,获取多语言信息。这一步,初始化MessageSource,如果在此context中没有定义任何值,则使用DelegatingMessageSource,实际是委派给父类的。

    initApplicationEventMulticaster

    初始化ApplicationEventMulticaster。如果上下文中没有定义,则使用SimpleApplicationEventMulticaster。

    onRefresh

    子类实现用于刷新context特殊的初始化工作,在实例化单例之前调用特定bean的初始化。

    registerListeners

    添加实现ApplicationListener接口,作为Listener的bean。不会影响其他Listener监听事件,添加是BeanName,而不是实例化后的Bean。Listener注册到ApplicationEventMulticaster。主要步骤:

    1. 注册ApplicationContext特定的Listener
    2. BeanFactory取出ApplicationListener的BeanNames,这里不初始化bean,而是注册Listener BeanName
    3. 广播earlyApplicationEvents

    finishBeanFactoryInitialization

    完成此上下文bean工厂的初始化,初始化所有剩余的单例bean。 与BeanFactory不同的是,ApplicationContext是eager模式,这一步主要是直接调用BeanFactory的初始化方法,完成所有non-lazy-init的bean的初始化

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
       // 初始化Context的类型转换服务。
       if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
             beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
          beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
       }
    
       // 注册一个默认的ValueResolver,主要是为了解决注解的属性值,默认用Environment的propertyResolver
       if (!beanFactory.hasEmbeddedValueResolver()) {
          beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
       }
    
       // 先初始化LoadTimeWeaverAware,用于运行时织入
       String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
       for (String weaverAwareName : weaverAwareNames) {
          getBean(weaverAwareName);
       }
    
       // Stop using the temporary ClassLoader for type matching.
       beanFactory.setTempClassLoader(null);
    
       // Allow for caching all bean definition metadata, not expecting further changes.
       beanFactory.freezeConfiguration();
    
       // 实例化所有剩余的(non-lazy-init)单例。
       beanFactory.preInstantiateSingletons();
    }
    

    实例化所有的bean就是遍历所有的beanNames,然后挨个调用getBean(beanName),bean的初始化在BeanFactory 源码分析已经分析过了。这里还有一步是检测SmartInitializingSingleton

    if (singletonInstance instanceof SmartInitializingSingleton) {
        final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
        smartSingleton.afterSingletonsInstantiated();
    }
    

    也就是说bean还可以实现SmartInitializingSingleton完成最后的init工作。

    finishRefresh

    完成此上下文的刷新,调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent。

    protected void finishRefresh() {
       // 清除context级资源缓存
       clearResourceCaches();
    
       // 为这个context初始化生命周期处理器,默认为DefaultLifecycleProcessor
       initLifecycleProcessor();
    
       // 刷新LifecycleProcessor,调用所有Lifecycle的start方法
       getLifecycleProcessor().onRefresh();
    
       // 发布事件
       publishEvent(new ContextRefreshedEvent(this));
    
       // 。。。好像是对JMX支持
       LiveBeansView.registerApplicationContext(this);
    }
    

    这个方法主要是对于有生命周期的bean,按照分组,调用其start方法。

    ApplicationContext 使用

    那么到此ApplicationContext初始化也就完成了,ApplicationContext可以作为BeanFactory、时间通知、资源管理使用

    // beanFactory
    UserService userService = context.getBean("userService", UserService.class);
    
    // 事件
    context.addApplicationListener(new WalkListener());
    context.publishEvent(new WalkEvent(new User("Jerry")));
    context.publishEvent(new WalkEvent(new User("Peter")));
    
    // locale
    context.getMessage("menu.edit", null, "Edit", Locale.US);
    // ...
    
    

    ApplicationContext的使用部分只需要调用内部的相应的组件即可。

    总结

    ApplicationContext 是Spring 的完整上下文,通过将各个功能模块委派给各个组件,完成了一个完成的环境,在ApplicationContext的构造函数中,完成各个组件的初始化,以备后期使用。

    相关文章

      网友评论

        本文标题:Spring IOC ApplicationContext 源码

        本文链接:https://www.haomeiwen.com/subject/zalxiftx.html