1. 文档

2. 启动流程

2.1. 初始化SpringApplication对象

  1. 初始化 primarySources , 并将命令行参数加入到 primarySources 中.

  2. 确定ApplicationType: None Web/Servlet/Reactive

  3. 获取 META-INF/spring.factories 中的 ApplicationContextInitializer 并设置到 SpringApplication 成员变量中.

    • DelegatingApplicationContextInitializer

    • SharedMetadataReaderFactoryContextInitializer

    • ContextIdApplicationContextInitializer

    • ConfigurationWarningsApplicationContextInitializer

    • RSocketPortInfoApplicationContextInitializer

    • ServerPortInfoApplicationContextInitializer

    • ConditionEvaluationReportLoggingListener

  4. 获取 META-INF/spring.factories 中的 ApplicationListener 并设置到 SpringApplication 成员变量中.

    • EnvironmentPostProcessorApplicationListener

    • AnsiOutputApplicationListener

    • LoggingApplicationListener

    • BackgroundPreinitializer

    • DelegatingApplicationListener

    • ParentContextCloserApplicationListener

    • ClearCachesApplicationListener

    • FileEncodingApplicationListener

  5. 设置启动类class对象.

2.2. 初始化Environment

  1. 创建 DefaultBootstrapContext , 执行 BootstrapRegistryInitializer#initialize 方法来扩展 DefaultBootstrapContext .

  2. META-INF/spring.factories 中获取所有的 SpringApplicationRunListener 封装进 SpringApplicationRunListeners .

  3. 发布 ApplicationStartingEvent

    • LoggingApplicationListener: 设置loggingSystem, 默认logback.

    • BackgroundPreInitializer.

    • DelegatingApplicationListener

  4. 根据 webApplicationType 初始化 Environment 对象.

    • SERVLET: ApplicationServletEnvironment

    • REACTIVE: ApplicationReactiveWebEnvironment

    • NONE: ApplicationEnvironment

  5. 读取系统属性, 设置到Environment中:

    • springApplicationCommandLineArgs 启动命令行参数

    • servletConfigInitParams

    • servletContextInitParams

    • systemProperties System.getProperties()

    • systemEnvironment System.getEnv()

    • defaultProperties

  6. 发布 ApplicationEnvironmentPreparedEvent

    • EnvironmentPostProcessorApplicationListener : 从 META-INF/spring.factories 中获取所有的 EnvironmentPostProcessor, 调用 EnvironmentPostProcessor#postProcessEnvironment() 方法 .

      • RandomValuePropertySourceEnvironmentPostProcessor : 新增一个获取随机数的 PropertySource , 加入到 Environment 中.

      • SystemEnvironmentPropertySourceEnvironmentPostProcessor : 把 systemEnvironmentPropertySource 包装成 OriginAwareSystemEnvironmentPropertySource , 能根据转换后的属性名获取到原始的属性名.

      • SpringApplicationJsonEnvironmentPostProcessor : 解析 spring.application.json 中的json配置, 加入到 Environment 中, 比systemProperties优先级高.

      • CloudFoundryVcapEnvironmentPostProcessor : 读取vcap属性, 加入到 Environment 中.

      • ConfigDataEnvironmentPostProcessor : 读取配置文件(properties/xml/yaml/yml) 中的配置项, 加入到 Environment 中.

      • IntegrationPropertiesEnvironmentPostProcessor : 读取 META-INF/spring.integration.properties 文件配置, 加入到 Environment 中.

      • DebugAgentEnvironmentPostProcessor : 如果引入的 ProjectReactor 包并开启了debug功能, 则调用 reactor.tools.agent.ReactorDebugAgent.init 方法.

    • AnsiOutputApplicationListener: 读取 spring.output.ansi.enabledspring.output.ansi.console-available 配置.

    • LoggingApplicationListener: 初始化 Log properties/system .

    • DelegatingApplicationListener: 向 context.listener.classes 中的listeners发送 ApplicationEnvironmentPreparedEvent 事件.

    • FileEncodingApplicationListener: 比较 file.encodingspring.mandatory-file-encoding 是否相同, 如果不同则抛出异常.

  7. default PropertySource 移动到最低优先级处.

  8. bindToSpringApplication: 将以 spring.main 开头的配置设置到 SpringApplication 属性中.

  9. 包装 Environment::propertySourcesConfigurationPropertySourcesPropertySource(key为configurationProperties) .

  10. spring.beaninfo.ignore 配置设置到系统属性中.

  11. 打印banner日志.

2.3. 初始化ApplicationContext

  1. 根据ApplicationType创建对应的context:

    • None-Web: AnnotationConfigApplicationContext

    • Servlet: AnnotationConfigServletWebServerApplicationContext

    • Reactive: AnnotationConfigReactiveWebServerApplicationContext

  2. 初始化 AnnotatedBeanDefinitionReader .

    • 设置BeanFactory属性.

      • AnnotationAwareOrderComparator

      • ContextAnnotationAutowireCandidateResolver

    • 注册spring内置BeanFactoryPostProcessor

      • ConfigurationClassPostProcessor

      • AutowiredAnnotationBeanPostProcessor

      • RequiredAnnotationBeanPostProcessor

      • CommonAnnotationBeanPostProcessor

      • PersistenceAnnotationBeanPostProcessor

      • EventListenerMethodProcessor

      • DefaultEventListenerFactory

  3. 初始化ClassPathBeanDefinitionScanner.

    • 初始化 includeFilters .

    • 读取 META-INF/spring.components 文件获取bean解析缓存.

  4. 调用 ApplicationContextInitializer::initialize .

    • DelegatingApplicationContextInitializer : 调用 context.initializer.classesinitialize 方法.

    • SharedMetadataReaderFactoryContextInitializer : 注册 CachingMetadataReaderFactoryPostProcessor 到容器中.

    • ContextIdApplicationContextInitializer : 设置 ApplicationContext 的 id 为 spring.application.name 配置项, 如果没配置则使用默认值 "application" .

    • ConfigurationWarningsApplicationContextInitializer : 注册 ConfigurationWarningsPostProcessor 到容器中.

    • RSocketPortInfoApplicationContextInitializer : 注册 org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer.Listener 到容器中.

    • ServerPortInfoApplicationContextInitializer : 将自己注册到context的 ApplicationListener 中.

    • ConditionEvaluationReportLoggingListener : 注册 ConditionEvaluationReportListener 到容器中.

  5. 发布 ApplicationContextInitializedEvent .

  6. 发布 BootstrapContextClosedEvent .

  7. 打印启动日志, 包括进程ID, 启动用户, profile等信息.

  8. 注册SpringBoot用到的一些bean到容器中: springApplicationArguments, springBootBanner, LazyInitializationBeanFactoryPostProcessor .

  9. 封装主启动类为 AnnotatedGenericBeanDefinition , 注册到BeanFactory中.

  10. 将SpringApplication中的listener添加到ApplicationContext中.

  11. 发布 ApplicationPreparedEvent .

    • SpringApplicationShutdownHook : 注册context关闭的listener.

2.4. refresh

  1. prepareRefresh: 初始化 earlyApplicationListeners .

  2. prepareBeanFactory:

    • 设置 classLoader/beanExpressionResolver/SPEL/ResourceEditorRegistrar 属性.

    • 注册BeanPostProcessor ApplicationContextAwareProcessor/ApplicationListenerDetector .

    • 注册 environment/systemProperties/systemEnvironment/applicationStartup Bean.

  3. postProcessBeanFactory: (Web环境下) 注册 WebApplicationContextServletContextAwareProcessor .

  4. invokeBeanFactoryPostProcessors: 按PriorityOrdered/Ordered/Regular顺序调用 BeanDefinitionRegistry#postProcessBeanDefinitionRegistry()BeanDefinitionRegistry#postProcessBeanFactory() , 再按顺序调用 BeanFactoryPostProcessor#postProcessBeanFactory()

    • CachingMetadataReadFactoryPostProcessor : 注册 SharedMetadataReaderFactoryBean , 并设置 ConfigurationClassPostProcessormetadataReaderFactory 属性为 SharedMetadataReaderFactoryBean .

    • ConfigurationWarningsPostProcessor : 检查扫描的包路径是否存在以 org/org.springframework 开头, 如果存在则打印warning日志.

    • ConfigurationClassPostProcessor :

      • 根据Configuration类扫描并注册 BeanDefinition .

      • 为Configuration类创建CGLIB代理.

      • 注册 ImportAwareBeanPostProcessor .

    • ConfigurationPropertiesBeanDefinitionValidator : 校验 @ConstructorBinding 必须和 @EnableConfigurationProperties或@ConfigurationPropertiesScan 一起使用.

    • PropertySourcesPlaceHolderConfigurer : 替换 ${…​} .

    • EventListenerMethodProcessor : 初始化 eventListenerFactories 属性.

    • PreserverErrorControllerTargetClassPostProcessor : 设置BasicErrorController为CGLIB代理.

  5. registerBeanPostProcessors: 注册beanPostProcessor:

    • ApplicationContextAwareProcessor

    • ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor

    • PostProcessorRegistrationDelegate.BeanPostProcessorChecker

    • ConfigurationPropertiesBindingPostProcessor

    • AnnotationAwareAspectJAutoProxyCreator

    • CommonAnnotationBeanPostProcessor

    • AutowiredAnnotationBeanPostProcessor

    • ApplicationListenerDetector

  6. initMessageSource: 注册MessageSource DelegatingMessageSource .

  7. initApplicationEventMulticaster: 注册ApplicationEventMulticaster SimpleApplicationEventMulticaster .

  8. onRefresh: 创建WebServer,将 servletContext 设置到 servletContextInitParams 中.

  9. registerListeners: 将 ApplicationListener 注册到 applicationEventMulticaster 中.

  10. finishBeanFactoryInitialization: 初始化Singleton的BeanDefinition.

  11. finishRefresh:

    • 注册lifeCycleProcessor bean 为 DefaultLifeCycleProcessor .

    • 调用实现了 SmartLifeCycle 接口的bean的start方法.

    • 发布 ContextRefreshedEvent .

    • ConditionEvaluationReportLoggingListener 打印Spring自动装配过滤bean的日志.

    • ClearCachesApplicationListener 清空Spring启动时反射类和类加载器的缓存.

    • SharedMetadataReaderFactoryBean 清空Bean的元数据缓存.

    • 启动WebServer.

    • 发布 ServletWebServerInitializedEvent .

  12. 清空Spring启动时使用到的各种缓存.

3. 单例bean初始化流程

  1. 遍历所有的bean, 筛选出非抽象类/单例/非懒加载的bean, 准备预先初始化.

  2. 根据beanName从三级缓存中查找, 如果存在, 则直接返回.

  3. 将beanName加入到 singletonsCurrentlyInCreation 集合中, 保证当前bean不被重复初始化.

  4. 解析bean的class对象, 调用 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法.

    • AbstractAutoProxyCreator : 判断是否需要创建代理对象, 如果需要, 则直接创建好并返回.

  5. 如果当前对象已经创建好, 则提前回调 BeanPostProcessor#postProcessAfterInitialization , 然后直接返回该对象, 创建过程直接结束.

  6. 获取bean的构造方法, 如果构造方法需要参数, 则注入参数, 具体注入实现见 ConstructorResolver#resolveAutowiredArgument, 如果注入的对象为lazy, 就会创建一个代理对象, 获取对象属性或者调用对象方法时才会创建真正的对象.

  7. 根据构造方法和参数创建bean对象.

  8. 回调 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 方法.

  9. 加入到三级缓存中.

  10. populateBean:

    • 回调 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 方法.

    • 回调 InstantiationAwareBeanPostProcessor#postProcessProperties 方法, 填充属性.

      • CommonAnnotationBeanPostProcessor .

      • AutowiredAnnotationBeanPostProcessor .

  11. initializeBean:

    • 回调 Aware 系接口.

    • 回调 BeanPostProcessor#postProcessBeforeInitialization 方法 (此处会回调自定义的init方法).

    • 回调 afterPropertiesSet() 方法.

    • 回调 BeanPostProcessor#postProcessAfterInitialization 方法.

  12. 如果bean存在回调方法, 则标记该bean到 disposableBeans 中.

    • 实现了 DisposableBean 接口.

    • 设置了 destroyMethod 属性.

    • 存在 @PreDestroy 注解的方法.

  13. 创建完毕, 将beanName从 singletonsCurrentlyInCreation 中删除.

  14. 将bean从二级/三级缓存中删除, 再加入到一级缓存中.

  15. 如果bean实现了 SmartInitializingSingleton 接口, 则回调 afterSingletonsInstantiated 方法.

3.1. 后置处理

  1. 打印启动日志.

  2. 发布 ApplicationStartedEvent .

  3. 调用 ApplicationRunner#run()和CommandLineRunner#run() .

  4. 发布 ApplicationReadyEvent .

  5. 发布 AvailabilityChangeEvent , 修改当前应用的状态为 ACCEPTING_TRAFFIC .

4. Spring Boot WebMvc 自动装配流程

  1. ServletWebServerFactoryAutoConfiguration : 根据项目的依赖创建 ServletWebServerFactory , 用来在Spring的 ApplicationContext refresh的时候创建一个WebServer, 并注册一些 BeanPostProcessor 用来定制化WebServer.

  2. DispatcherServletAutoConfiguration : 注册 DispatcherServlet.

  3. WebMvcAutoConfiguration : 注册一些 SpringMVC 的组件, 如 ViewResolver , ViewResolver , RequestMappingHandler , RequestMappingHandlerMapping , Validator, ExceptionHandlerExceptionResolver 等.

5. Spring IoC

5.1. 从外部导入Bean的方式

  • @Import 直接导入Bean类.

  • @Import 导入 @Configuration 类.

  • @Import 导入 ImportSelector 接口的实现类.

  • @Import 导入 ImportBeanDefinitionRegistrar 接口的实现类.

BeanImportDemo.java
package me.jy.bean.external;

import lombok.Data;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @author jy
 */
@SpringBootApplication
public class BeanImportDemo {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(BeanImportDemo.class, args);
//        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanAutoRegisterConfiguration.class);
        System.out.println(context.getBeansOfType(Universe.class));
    }


    @Import({Universe.class, DemoImportSelector.class, OuterConfiguration.class, DemoBeanDefinitionRegistrar.class})
    @Configuration
    public static class BeanAutoRegisterConfiguration {
    }

    public static class DemoBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            registry.registerBeanDefinition("ImportBeanDefinitionRegistrarUniverse", new RootBeanDefinition(Universe.class));
        }
    }

    public static class DemoImportSelector implements ImportSelector {
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return new String[]{ImportUniverse.class.getName()};
        }
    }

    @Configuration
    public static class OuterConfiguration {
        @Bean
        public Universe outerUniverse() {
            return new Universe().setName("OuterUniverse");
        }
    }

    @Data
    public static class Universe {
        private String name;
    }

    public static class ImportUniverse extends Universe {
    }
}

6. Spring AoP

6.1. 术语

  • Aspect: 声明需要关注的类/方法的一个地方.

  • JoinPoint: 代表正在执行的方法.

  • Advice: 表示JoinPoint何时被执行, 如 Before, AfterReturning, AfterThrowing, After, Around.

  • Pointcut: 连接点匹配判断.

  • Introduction: 为特定类型声明额外的方法/属性.

  • Target object: 被AOP的原始对象.

  • AOP proxy: 被AOP框架生成代理的对象.

  • Weaving: 基于普通对象和切面生成代理对象的过程, 可以在编译时/加载时/运行时进行.

6.2. Pointcut

  • 匹配方法

  • execution: execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)

  • 匹配包/类型

    • within

  • 匹配对象

    • this

    • bean

    • target

  • 匹配注解

    • @target: RetentionPolicy为class

    • @args

    • @within: RetentionPolicy为runtime

    • @annotation

  • 匹配参数

    • args

示例:
execution(public * *(..)) // 匹配所有公共方法
execution(* set*(..)) // 匹配所有以set开头的方法
execution(* com.xyz.service.AccountService.*(..)) // 匹配AccountService里所有的方法
execution(* com.xyz.service.*.*(..)) // 匹配com.xyz.service包下所有的方法
execution(* com.xyz.service..*.*(..)) // 匹配com.xyz.service包及其子包下所有的方法

within(com.xyz.service.*) // 匹配com.xyz.service包下所有的方法
within(com.xyz.service..*) // 匹配com.xyz.service包及其子包下所有的方法

this(com.xyz.service.AccountService) // 匹配AccountService所有子类里的方法
target(com.xyz.service.AccountService)

bean(tradeService) // 匹配beanName为"tradeService"的类下的方法.
bean(*Service) // 匹配beanName以"Service"结尾的类下的方法.

args(java.io.Serializable) // 匹配参数只有一个并且类型为Serializable的方法

@target(org.springframework.transaction.annotation.Transactional) // 匹配有@Transactional注解的类下的方法
@within(org.springframework.transaction.annotation.Transactional)
@annotation(org.springframework.transaction.annotation.Transactional) // 匹配有@Transactional注解的方法
@args(com.xyz.security.Classified) // 匹配参数只有一个并且参数上有@Classified的方法

6.3. Aop注册流程

  1. 解析Configuration类的 @EnableAspectJAutoProxy 注解, 注册 AnnotationAwareAspectJAutoProxyCreator .

  2. postProcessBeforeInstantiation 时扫描所有的Aspect, 标记出所有需要被aop的bean.

  3. postProcessAfterInitialization 时创建代理对象.

    1. 根据 AopUtils.findAdvisorsThatCanApply 找到每个bean的advisor.

    2. 使用 CGLIB 生成代理类, 使用 sun.reflect.ReflectionFactory 创建代理对象.

7. Spring TX

7.1. Spring Transaction切面注册流程

  1. 解析Configuration类的 @EnableTransactionManagement 注解, 注册 AutoProxyRegistrar, ProxyTransactionManagementConfiguration .

  2. 导入Configuration类 ProxyTransactionManagementConfiguration , 注册以下bean:

    • transactionalEventListenerFactory: 处理事件

    • transactionAttributeSource: 定义advisor的pointcut

    • transactionInterceptor: 事务advice

    • transactionAdvisor: 事务advisor

  3. AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization 会根据 transactionAttributeSource 解析并缓存 @Transactional 方法/类上的注解.

7.2. TransactionDefinition

7.2.1. Propagation

Propagation类型 行为

PROPAGATION_REQUIRED(默认)

如果当前存在一个事务, 则加入到该事务, 如果事务回滚, 则一起回滚.

PROPAGATION_SUPPORTS

如果当前存在一个事务, 则加入到该事务, 否则以非事务的方式运行.

PROPAGATION_MANDATORY

如果当前存在一个事务, 则加入到该事务, 如果当前没有事务运行, 则抛出异常.

PROPAGATION_NESTED

如果当前存在一个事务, 标记当前为savepoint, 如果事务回滚, 则只会回滚到savepoint.

PROPAGATION_REQUIRES_NEW

如果当前存在一个事务, 则当前事务挂起, 然后新开一个事务.

PROPAGATION_NOT_SUPPORTED

如果当前存在一个事务, 则将该事务挂起, 然后以非事务的方式运行.

PROPAGATION_NEVER

以非事务的方式运行, 如果当前存在一个事务, 则抛出异常.

PROPAGATION_REQUIRED/PROPAGATION_REQUIRES_NEW/PROPAGATION_NESTED 下如果当前不存在事务, 则新开一个事务.

7.2.2. timeout

如果事务没有在指定时间内完成, 则自动回滚事务.

7.2.3. readOnly

如果事务的操作只是读取资源, 则可以设置readOnly为true, 提高事务性能.

7.2.4. rollback

默认方法抛出 RuntimeException 时才回滚事务, 可以主动设置rollback条件.

7.3. TransactionStatus

  • boolean isNewTransaction(); //是否是新的事物

  • boolean hasSavepoint(); // 是否有恢复点

  • void setRollbackOnly(); // 设置为只回滚

  • boolean isRollbackOnly(); // 是否为只回滚

  • boolean isCompleted; // 是否已完成

8. SpringBoot属性配置优先级

  1. Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).

  2. @TestPropertySource annotations on your tests.

  3. @SpringBootTest#properties annotation attribute on your tests.

  4. Command line arguments.

  5. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).

  6. ServletConfig init parameters.

  7. ServletContext init parameters.

  8. JNDI attributes from java:comp/env.

  9. Java System properties (System.getProperties()).

  10. OS environment variables.

  11. A RandomValuePropertySource that has properties only in random.*.

  12. Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).

  13. Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).

  14. Application properties outside of your packaged jar (application.properties and YAML variants).

  15. Application properties packaged inside your jar (application.properties and YAML variants).

  16. @PropertySource annotations on your @Configuration classes.

  17. Default properties (specified by setting SpringApplication.setDefaultProperties).