Spring源码分析(一) - 概述以及Bean的创建

应用上下文创建流程概览

spring1.png

源码剖析

  1. 创建Spring应用程序上下文
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  1. 进入ClassPathXmlApplicationContext构造函数
public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {

        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

(1)调用父类构造方法,创建Reslover,解析配置文件
(2)设置配置文件路径到当前应用程序中
(3)开始调用refresh(),进行容器的创建

  1. 进入refresh()方法
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

(1) prepareRefresh:做前期准备

  • 设置容器的启动时间
  • 设置活跃状态为true
  • 设置关闭状态为false
  • 获取Environment对象,并加载当前系统的属性值到Environment对象中
  • 准备监听器和事件对象的集合

(2) obtainFreshBeanFactory
创建容器并完成配置文件加载

(3) prepareBeanFactory
通过一系列的add, set, ignore, register开头的方法,给容器对象进行赋值

(4) postProcessBeanFactory: 默认没有实现,留给子类去实现

(5) invokeBeanFactoryPostProcessors
可进行自由扩展,修改BeanFactory的相关信息。比如:ConfigurationClassPostProcessor, PropertySourcePlaceHolderConfigurer

(6) registerBeanPostProcessors
注册BeanPostProcessor,完成spring自带的或者用户自定义的BeanPostProcessor的解析

(7) initMessageSource
进行国际化相关的操作

(8) initApplicationEventMulticaster
初始化事件广播器

(9) onRefresh: 默认没有实现,由子类去定义

(10) registerListener: 注册监听器,接收广播的事件

(11) finishBeanFactoryInitialization:完成对象的实例化操作
从此方法开始进行对象的创建,包含实例化,初始化,循环依赖,AOP等核心逻辑的处理过程。

(12) finishRefresh
完成整个容器的启动,所有对象都准备完成。清除上下午缓存,初始化生命周期处理器,并发送刷新完成事件。

Bean的创建

前面说到了在finishBeanFactoryInitialization()方法中会进行对象的创建。下面来进一步看下Bean是如何创建的:

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));
        }

        // Register a default embedded value resolver if no bean post-processor
        // (such as a PropertyPlaceholderConfigurer bean) registered any before:
        // at this point, primarily for resolution in annotation attribute values.
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        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();

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

(1)setConversionService:设置类型转换服务
(2)addEmbeddedValueResolver:设置内置的值处理器
(3)freezeConfiguration:冻结BeanDefinition
(4)preInstantiateSingletons(关键步骤):
开始对象的实例化:

        // Iterate over a copy to allow for init methods which in turn register new bean definitions.
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }

从容器中获取所有的BeanDefinitionNames集合,从每个集合中获取每一个元素,来进行对象的创建。

根据BeanName来获取完整的BeanDefinition对象。再通过getBean()来获取Bean对象,里面调用的doGetBean()。

这其中涉及到整个Bean的创建,属性填充,实例化等一些列操作,大致流程如下:


bean.png

这其中涉及到spring对Bean对象的三级缓存,后面会再来详细说下这个问题。

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

推荐阅读更多精彩内容