spring-framework源码导入

  1. 直接从github找到repo,克隆到本地:

    1. cd ~/IdeaProjects
    2. git clone https://github.com/spring-projects/spring-framework.git
  2. 将下载源替换为阿里的源:

    cd ~/.gradle
    vim init.gradle
    

    init.gradle:

    allprojects{
     repositories {
         google()
         def ALIYUN_REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public'
         def ALIYUN_JCENTER_URL = 'http://maven.aliyun.com/nexus/content/repositories/jcenter'
         all { ArtifactRepository repo ->
             if(repo instanceof MavenArtifactRepository){
                 def url = repo.url.toString()
                 if (url.startsWith('https://repo1.maven.org/maven2')) {
                     project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_REPOSITORY_URL."
                     remove repo
                 }
                 if (url.startsWith('https://jcenter.bintray.com/')) {
                     project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_JCENTER_URL."
                     remove repo
                 }
             }
         }
         maven { url ALIYUN_REPOSITORY_URL }
         maven { url ALIYUN_JCENTER_URL }
     }
    }
    
  3. 使用Idea打开spring-framework/build.gradle,在Gradle中import即可。

  4. 使用Tasks/others/compileTestJava进行编译:core -> oxm -> context -> beans -> aspects -> aop。

Spring IoC容器初始化流程

顶级接口BeanFactory的结构

image.png

BeanFactory容器继承体系

Spring IoC源码分析 - 图2

Bean周期关键时机点调用分析

关键点和触发代码:

关键点 触发代码
构造器 refresh#finishBeanFactoryInitialization(beanFactory)(beanFactory)
BeanFactoryPostProcessor初始化
refresh#invokeBeanFactoryPostProcessors(beanFactory)
BeanFactoryPostProcessor方法调用 refresh#invokeBeanFactoryPostProcessors(beanFactory)
BeanPostProcessor初始化 registerBeanPostProcessors(beanFactory)
BeanPostProcessor方法调用 refresh#finishBeanFactoryInitialization(beanFactory)

AbstractApplicationContext的refresh方法:


@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        // 1. 刷新前的预处理
        /**
         * Prepare this context for refreshing, setting its startup date and
         * active flag as well as performing any initialization of property sources.
         */
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        // 2. 获取BeanFactory。默认实现是返回DefaultListableBeanFactory。
        // 加载BeanDefinition,并注册到BeanDefinitionRegistry。
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 3. BeanFactory的预准备工作(BeanFactory进行一些设置,如context的类加载器等)
        /**
         * Configure the factory's standard context characteristics,
         * such as the context's ClassLoader and post-processors.
         * @param beanFactory the BeanFactory to configure
         */
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            // 4. BeanFactory准备工作完成后进行的后置处理工作。
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            // 5. 实例化并调用实现了BeanFactoryPostProcessor接口的Bean。
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 6. 注册BeanPostProcessor(Bean的后置处理器),在创建的bean的前后执行。
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            // 7. 初始化MessageSource组件(做国际化功能;消息绑定,消息解析)。
            initMessageSource();

            // Initialize event multicaster for this context.
            // 8. 初始化事件派发器。
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            // 9. 子类重写这个方法,在容器刷新的时候可以自定义逻辑。
            onRefresh();

            // Check for listener beans and register them.
            // 10. 注册应用的监听器,即注册实现了ApplicationListener接口的监听器bean。
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            // 11. 初始化所有剩下的非懒加载的单例bean
            //   1. 初始化创建非懒加载方式的单例Bean实例,此时未设置属性
            //   2. 填充属性
            //   3. 初始化方法调用(如afterPropertiesSet方法、init-method属性设置的方法)
            //   4. 调用BeanPostProcessor对实例bean进行后置处理
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            // 12. 完成context的刷新,主要是调用LifecycleProcessor的onRefresh方法,并发布事件ContextRefreshedEvent。
            finishRefresh();
        }

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

BeanFactory创建流程

BeanFactory获取子流程

Spring IoC源码分析 - 图3

BeanDefinition加载注册子流程

关键步骤:

  1. Resource定位。对BeanDefinition的资源定位过程。就是找到定义JavaBean信息的xml文件,并将其封装成Resource对象。
  2. BeanDefinition载入。把用户定义好的JavaBean表示为IoC容器内部的数据结构,该数据结构就是BeanDefinition。
  3. 注册BeanDefinition到IoC容器。 Spring IoC源码分析 - 图4

    Bean创建流程

lazy-init延迟加载机制原理

Spring IoC循环依赖问题

Spring IoC源码分析 - 图5