spring源码解析 — Spring Context

源码分析基于spring 4.3.x

本文通过阅读源码分析Spring Context​。

关于阅读源码的思路,可参考 — 如何阅读java源码

前面解析spring构造bean过程的文章说过时,spring会查找上下文中用户定义的BeanPostProcessor并进行相应操作,那么这些扩展的BeanPostProcessor是怎样进入spring的呢?

这里就要说到Spring Context模块了。

Spring Context模块增加了对国际化(例如使用资源包),事件传播,资源加载,透明创建上下文(如Servlet容器)的支持,而将用户定义的BeanPostProcessor加载到spring,正是Spring Context的工作。

ApplicationContext接口是Context模块的核心。

AbstractApplicationContext是ApplicationContext接口的基础实现类。

核心方法AbstractApplicationContext#refresh

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        
        prepareRefresh();    // #1

        
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();    // #2


        prepareBeanFactory(beanFactory);    // #3

        try {
            postProcessBeanFactory(beanFactory);    // #4


            invokeBeanFactoryPostProcessors(beanFactory);    // #5

            registerBeanPostProcessors(beanFactory);    // #6

            initMessageSource();    // #7

            
            initApplicationEventMulticaster();    // #8

            onRefresh();    // #9

            registerListeners();    // #10

            
            finishBeanFactoryInitialization(beanFactory);    // #11

            finishRefresh();    // #12
        }
        catch (BeansException ex) {
            ...
            destroyBeans();    // #13
            
            cancelRefresh(ex);    // #14
            
            throw ex;
        } finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

#1 准备刷新上下文环境

#2 初始化BeanFactory,并加载bean definitions信息

#3 对beanFacotry进行配置

#4 提供给子类扩展的预留方法

#5 激活BeanFactoryPostProcessors

#6 注册BeanPostProcessors

#7 初始化MessageSource

#8 初始化事件广播器

#9 提供给子类初始化其他的Bean

#10 注册事件监听器

#11 构造热加载单例bean

#12 完成刷新过程,通知生命周期处理器

#13 出错了,销毁bean

#14 出错了,修改active标识

AbstractApplicationContext#obtainFreshBeanFactory -> AbstractRefreshableApplicationContext#refreshBeanFactory

protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {    // #1
        destroyBeans();
        closeBeanFactory();
    }
    try {
        DefaultListableBeanFactory beanFactory = createBeanFactory();    // #2
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);    // #3
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

#1 如果已存在BeanFactory,销毁原来的BeanFactory

#2 创建DefaultListableBeanFactory

#3 加载bean definitions信息,loadBeanDefinitions是抽象方法,不同实现类会从不同的配置中获取bean definitions信息,如AnnotationConfigWebApplicationContext,XmlWebApplicationContext。

激活BeanFactoryPostProcessors

BeanFactoryPostProcessor是spring提供的扩展接口,可以通过BeanFactoryPostProcessor对beanFactory进行自定义处理,如修改其他BeanDefinition的配置。

AbstractApplicationContext#invokeBeanFactoryPostProcessors -> PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    Set<String> processedBeans = new HashSet<String>();

    if (beanFactory instanceof BeanDefinitionRegistry) {    // #1
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
        List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
                new LinkedList<BeanDefinitionRegistryPostProcessor>();

        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {    // #2
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryPostProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                registryPostProcessors.add(registryPostProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }

        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);    // #3

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
        List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));        // #4
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);        // #5
        registryPostProcessors.addAll(priorityOrderedPostProcessors);    // #6
        invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);    // #7

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
        for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {    // #8
                orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(beanFactory, orderedPostProcessors);    
        registryPostProcessors.addAll(orderedPostProcessors);
        invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);    

        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {    // #9
                    BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                    registryPostProcessors.add(pp);
                    processedBeans.add(ppName);
                    pp.postProcessBeanDefinitionRegistry(registry);
                    reiterate = true;
                }
            }
        }

        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);    
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);    
    }

    ...
}

BeanFactoryPostProcessor可以调整beanFactory,甚至修改BeanDefinition,如CustomEditorConfigurer,将用户定义的PropertyEditor注册到beanFactory中,以便后续使用。

BeanDefinitionRegistryPostProcessor可以注册新的BeanDefinition,如ConfigurationClassPostProcessor,是实现springboot很关键的类

#1 如果beanFactory是BeanDefinitionRegistry,需要处理BeanFactoryPostProcessors,BeanDefinitionRegistryPostProcessor,否则只处理BeanFactoryPostProcessors

#2 方法参数beanFactoryPostProcessors是AbstractApplicationContext#beanFactoryPostProcessors属性,用户可以通过AbstractApplicationContext#addBeanFactoryPostProcessor方法添加BeanFactoryPostProcessor。这里对beanFactoryPostProcessors参数进行分类

#3 获取beanFactory已经存在的BeanDefinitionRegistryPostProcessor 这里并没有直接构建BeanDefinitionRegistryPostProcessor,而且通过beanName获取

#4 获取实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,添加到priorityOrderedPostProcessors

#5 对priorityOrderedPostProcessors排序

#6 排序结果添加到registryPostProcessors

#7 调用BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry

#8 处理实现了Ordered的BeanDefinitionRegistryPostProcessor

#9 处理剩余的BeanDefinitionRegistryPostProcessor

beanFactoryPostProcessors的处理不在贴出了。

注册BeanPostProcessors

PostProcessorRegistrationDelegate#registerBeanPostProcessors会找到用户定义的BeanPostProcessor, 并注册到spring中,spring构造bean时会使用到它们。

PostProcessorRegistrationDelegate#registerBeanPostProcessors类似,获取上下文中的BeanPostProcessor,不过这里不会调用BeanPostProcessor的方法,只是注册到beanFactory中,在构建bean时再调用BeanPostProcessors对应的方法。

PostProcessorRegistrationDelegate#registerBeanPostProcessors

private static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

    for (BeanPostProcessor postProcessor : postProcessors) {
        beanFactory.addBeanPostProcessor(postProcessor);
    }
}

初始化事件广播器

Spring事件体系包括三个组件:ApplicationEvent事件,ApplicationListener事件监听器,ApplicationEventMulticaster事件广播器。

事件广播器负责管理事件监听器,并将事件广播给监听器。

AbstractApplicationContext#initApplicationEventMulticaster

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);    //#1
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);    //#2
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                    APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                    "': using default [" + this.applicationEventMulticaster + "]");
        }
    }
}

#1 使用用户定义的事件广播器

#2 使用默认的事件广播器

spring提供了context start,stop,close,refresh等事件,ApplicationListener#onApplicationEvent负责处理spring中的事件。我们可以通过实现ApplicationListener接口自行处理事件,也可以通过PublishListener自定义事件监听器。

使用默认的事件广播器 AbstractApplicationContexton#publishEvent -> SimpleApplicationEventMulticaster#multicastEvent

public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        Executor executor = getTaskExecutor();    // #1
        if (executor != null) {
            executor.execute(new Runnable() {
                public void run() {
                    invokeListener(listener, event);
                }
            });
        }
        else {
            invokeListener(listener, event);    // #2
        }
    }
}

#1 如果配置了Executor,使用Executor多线程处理

#2 否则单线程处理

事件处理就是遍历所有的事件监听器,调用ApplicationListener#onApplicationEvent。

注册事件监听器

AbstractApplicationContext#registerListeners将初始化事件监听器ApplicationListener,并绑定到事件广播器上。

protected void registerListeners() {
    for (ApplicationListener<?> listener : getApplicationListeners()) {    // #1
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);    // #2
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;    // #3
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

#1 getApplicationListeners()获取的是AbstractApplicationContext#applicationListeners,用户可以通过AbstractApplicationContext#addApplicationListener添加事件监听器

将AbstractApplicationContext#applicationListeners注册到applicationEventMulticaster

#2 将上下文中的ApplicationListener注册到applicationEventMulticaster

#3 发布在此之前已发生的事件

构造热加载单例bean

AbstractApplicationContext#finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this 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));    //#1
    }

    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {    //#2
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }

    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);    //#3
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    beanFactory.setTempClassLoader(null);

    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    beanFactory.preInstantiateSingletons();    //#4
}

#1 初始化ConversionService,后面注入属性要使用

#2 初始化StringValueResolver,用于解析bean属性引用的properties配置

#3 初始化LoadTimeWeaverAware

#4 构造热加载单例bean

AbstractApplicationContext#preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
    ...

    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {    // #1
            if (isFactoryBean(beanName)) {
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                            @Override
                            public Boolean run() {
                                return ((SmartFactoryBean<?>) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
            }
            else {
                getBean(beanName);    // #2
            }
        }
    }
    ...
}

#1 判断是否为非抽象类的热加载单例bean

#2 构造bean

如果非FactoryBean,构造bean。

如果FactoryBean并且FactoryBean.isEagerInit为true,构造bean。

finishRefresh

protected void finishRefresh() {
    // Initialize lifecycle processor for this context.
    initLifecycleProcessor();    // #1

    // Propagate refresh to lifecycle processor first.
    getLifecycleProcessor().onRefresh();    // #2

    // Publish the final event.
    publishEvent(new ContextRefreshedEvent(this));    // #4

    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
}

#1 初始化LifecycleProcessor

#2 调用LifecycleProcessor#onRefresh()方法

#3 发布事件

LifecycleProcessor也是spring提供的扩展点, 通过它可以在spring content start,stop,onRefresh等时刻自定义一些额外操作。

这里主要讲了spring context的相关内容,讲的比较简单, 有兴趣的同学可以自行深入阅读源码。

如果您觉得本文不错,欢迎关注我的微信公众号,您的关注是我坚持的动力!

spring源码解析 -- Spring Context

原文 

https://segmentfault.com/a/1190000022537955

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » spring源码解析 — Spring Context

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址