2. 启动流程
2.1. 初始化SpringApplication对象
-
初始化
primarySources, 并将命令行参数加入到primarySources中. -
确定ApplicationType: None Web/Servlet/Reactive
-
获取
META-INF/spring.factories中的ApplicationContextInitializer并设置到SpringApplication成员变量中.-
DelegatingApplicationContextInitializer
-
SharedMetadataReaderFactoryContextInitializer
-
ContextIdApplicationContextInitializer
-
ConfigurationWarningsApplicationContextInitializer
-
RSocketPortInfoApplicationContextInitializer
-
ServerPortInfoApplicationContextInitializer
-
ConditionEvaluationReportLoggingListener
-
-
获取
META-INF/spring.factories中的ApplicationListener并设置到SpringApplication成员变量中.-
EnvironmentPostProcessorApplicationListener
-
AnsiOutputApplicationListener
-
LoggingApplicationListener
-
BackgroundPreinitializer
-
DelegatingApplicationListener
-
ParentContextCloserApplicationListener
-
ClearCachesApplicationListener
-
FileEncodingApplicationListener
-
-
设置启动类class对象.
2.2. 初始化Environment
-
创建
DefaultBootstrapContext, 执行BootstrapRegistryInitializer#initialize方法来扩展DefaultBootstrapContext. -
从
META-INF/spring.factories中获取所有的SpringApplicationRunListener封装进SpringApplicationRunListeners. -
发布 ApplicationStartingEvent
-
LoggingApplicationListener: 设置loggingSystem, 默认logback.
-
BackgroundPreInitializer.
-
DelegatingApplicationListener
-
-
根据
webApplicationType初始化Environment对象.-
SERVLET:
ApplicationServletEnvironment -
REACTIVE:
ApplicationReactiveWebEnvironment -
NONE:
ApplicationEnvironment
-
-
读取系统属性, 设置到Environment中:
-
springApplicationCommandLineArgs
启动命令行参数 -
servletConfigInitParams
-
servletContextInitParams
-
systemProperties
System.getProperties() -
systemEnvironment
System.getEnv() -
defaultProperties
-
-
发布 ApplicationEnvironmentPreparedEvent
-
EnvironmentPostProcessorApplicationListener: 从META-INF/spring.factories中获取所有的EnvironmentPostProcessor, 调用EnvironmentPostProcessor#postProcessEnvironment()方法 .-
RandomValuePropertySourceEnvironmentPostProcessor: 新增一个获取随机数的PropertySource, 加入到Environment中. -
SystemEnvironmentPropertySourceEnvironmentPostProcessor: 把systemEnvironment的PropertySource包装成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.enabled和spring.output.ansi.console-available配置. -
LoggingApplicationListener: 初始化
Log properties/system. -
DelegatingApplicationListener: 向
context.listener.classes中的listeners发送ApplicationEnvironmentPreparedEvent事件. -
FileEncodingApplicationListener: 比较
file.encoding和spring.mandatory-file-encoding是否相同, 如果不同则抛出异常.
-
-
将
default PropertySource移动到最低优先级处. -
bindToSpringApplication: 将以
spring.main开头的配置设置到SpringApplication属性中. -
包装
Environment::propertySources为ConfigurationPropertySourcesPropertySource(key为configurationProperties). -
将
spring.beaninfo.ignore配置设置到系统属性中. -
打印banner日志.
2.3. 初始化ApplicationContext
-
根据ApplicationType创建对应的context:
-
None-Web:
AnnotationConfigApplicationContext -
Servlet:
AnnotationConfigServletWebServerApplicationContext -
Reactive:
AnnotationConfigReactiveWebServerApplicationContext
-
-
初始化
AnnotatedBeanDefinitionReader.-
设置BeanFactory属性.
-
AnnotationAwareOrderComparator
-
ContextAnnotationAutowireCandidateResolver
-
-
注册spring内置BeanFactoryPostProcessor
-
ConfigurationClassPostProcessor
-
AutowiredAnnotationBeanPostProcessor
-
RequiredAnnotationBeanPostProcessor
-
CommonAnnotationBeanPostProcessor
-
PersistenceAnnotationBeanPostProcessor
-
EventListenerMethodProcessor
-
DefaultEventListenerFactory
-
-
-
初始化ClassPathBeanDefinitionScanner.
-
初始化
includeFilters. -
读取
META-INF/spring.components文件获取bean解析缓存.
-
-
调用
ApplicationContextInitializer::initialize.-
DelegatingApplicationContextInitializer: 调用context.initializer.classes的initialize方法. -
SharedMetadataReaderFactoryContextInitializer: 注册CachingMetadataReaderFactoryPostProcessor到容器中. -
ContextIdApplicationContextInitializer: 设置ApplicationContext的 id 为spring.application.name配置项, 如果没配置则使用默认值 "application" . -
ConfigurationWarningsApplicationContextInitializer: 注册ConfigurationWarningsPostProcessor到容器中. -
RSocketPortInfoApplicationContextInitializer: 注册org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer.Listener到容器中. -
ServerPortInfoApplicationContextInitializer: 将自己注册到context的ApplicationListener中. -
ConditionEvaluationReportLoggingListener: 注册ConditionEvaluationReportListener到容器中.
-
-
发布 ApplicationContextInitializedEvent .
-
发布 BootstrapContextClosedEvent .
-
打印启动日志, 包括进程ID, 启动用户, profile等信息.
-
注册SpringBoot用到的一些bean到容器中:
springApplicationArguments, springBootBanner, LazyInitializationBeanFactoryPostProcessor. -
封装主启动类为
AnnotatedGenericBeanDefinition, 注册到BeanFactory中. -
将SpringApplication中的listener添加到ApplicationContext中.
-
发布 ApplicationPreparedEvent .
-
SpringApplicationShutdownHook: 注册context关闭的listener.
-
2.4. refresh
-
prepareRefresh: 初始化
earlyApplicationListeners. -
prepareBeanFactory:
-
设置
classLoader/beanExpressionResolver/SPEL/ResourceEditorRegistrar属性. -
注册BeanPostProcessor
ApplicationContextAwareProcessor/ApplicationListenerDetector. -
注册
environment/systemProperties/systemEnvironment/applicationStartupBean.
-
-
postProcessBeanFactory: (Web环境下) 注册
WebApplicationContextServletContextAwareProcessor. -
invokeBeanFactoryPostProcessors: 按PriorityOrdered/Ordered/Regular顺序调用
BeanDefinitionRegistry#postProcessBeanDefinitionRegistry()和BeanDefinitionRegistry#postProcessBeanFactory(), 再按顺序调用BeanFactoryPostProcessor#postProcessBeanFactory()-
CachingMetadataReadFactoryPostProcessor: 注册SharedMetadataReaderFactoryBean, 并设置ConfigurationClassPostProcessor的metadataReaderFactory属性为SharedMetadataReaderFactoryBean. -
ConfigurationWarningsPostProcessor: 检查扫描的包路径是否存在以org/org.springframework开头, 如果存在则打印warning日志. -
ConfigurationClassPostProcessor:-
根据Configuration类扫描并注册
BeanDefinition. -
为Configuration类创建CGLIB代理.
-
注册
ImportAwareBeanPostProcessor.
-
-
ConfigurationPropertiesBeanDefinitionValidator: 校验@ConstructorBinding必须和@EnableConfigurationProperties或@ConfigurationPropertiesScan一起使用. -
PropertySourcesPlaceHolderConfigurer: 替换${…}. -
EventListenerMethodProcessor: 初始化eventListenerFactories属性. -
PreserverErrorControllerTargetClassPostProcessor: 设置BasicErrorController为CGLIB代理.
-
-
registerBeanPostProcessors: 注册beanPostProcessor:
-
ApplicationContextAwareProcessor -
ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor -
PostProcessorRegistrationDelegate.BeanPostProcessorChecker -
ConfigurationPropertiesBindingPostProcessor -
AnnotationAwareAspectJAutoProxyCreator -
CommonAnnotationBeanPostProcessor -
AutowiredAnnotationBeanPostProcessor -
ApplicationListenerDetector
-
-
initMessageSource: 注册MessageSource
DelegatingMessageSource. -
initApplicationEventMulticaster: 注册ApplicationEventMulticaster
SimpleApplicationEventMulticaster. -
onRefresh: 创建WebServer,将
servletContext设置到servletContextInitParams中. -
registerListeners: 将
ApplicationListener注册到applicationEventMulticaster中. -
finishBeanFactoryInitialization: 初始化Singleton的BeanDefinition.
-
finishRefresh:
-
注册lifeCycleProcessor bean 为
DefaultLifeCycleProcessor. -
调用实现了
SmartLifeCycle接口的bean的start方法. -
发布 ContextRefreshedEvent .
-
ConditionEvaluationReportLoggingListener打印Spring自动装配过滤bean的日志. -
ClearCachesApplicationListener清空Spring启动时反射类和类加载器的缓存. -
SharedMetadataReaderFactoryBean清空Bean的元数据缓存. -
启动WebServer.
-
发布 ServletWebServerInitializedEvent .
-
-
清空Spring启动时使用到的各种缓存.
3. 单例bean初始化流程
-
遍历所有的bean, 筛选出非抽象类/单例/非懒加载的bean, 准备预先初始化.
-
根据beanName从三级缓存中查找, 如果存在, 则直接返回.
-
将beanName加入到
singletonsCurrentlyInCreation集合中, 保证当前bean不被重复初始化. -
解析bean的class对象, 调用
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法.-
AbstractAutoProxyCreator: 判断是否需要创建代理对象, 如果需要, 则直接创建好并返回.
-
-
如果当前对象已经创建好, 则提前回调
BeanPostProcessor#postProcessAfterInitialization, 然后直接返回该对象, 创建过程直接结束. -
获取bean的构造方法, 如果构造方法需要参数, 则注入参数, 具体注入实现见
ConstructorResolver#resolveAutowiredArgument, 如果注入的对象为lazy, 就会创建一个代理对象, 获取对象属性或者调用对象方法时才会创建真正的对象. -
根据构造方法和参数创建bean对象.
-
回调
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition方法. -
加入到三级缓存中.
-
populateBean:
-
回调
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation方法. -
回调
InstantiationAwareBeanPostProcessor#postProcessProperties方法, 填充属性.-
CommonAnnotationBeanPostProcessor. -
AutowiredAnnotationBeanPostProcessor.
-
-
-
initializeBean:
-
回调
Aware系接口. -
回调
BeanPostProcessor#postProcessBeforeInitialization方法 (此处会回调自定义的init方法). -
回调
afterPropertiesSet()方法. -
回调
BeanPostProcessor#postProcessAfterInitialization方法.
-
-
如果bean存在回调方法, 则标记该bean到
disposableBeans中.-
实现了
DisposableBean接口. -
设置了
destroyMethod属性. -
存在
@PreDestroy注解的方法.
-
-
创建完毕, 将beanName从
singletonsCurrentlyInCreation中删除. -
将bean从二级/三级缓存中删除, 再加入到一级缓存中.
-
如果bean实现了
SmartInitializingSingleton接口, 则回调afterSingletonsInstantiated方法.
3.1. 后置处理
-
打印启动日志.
-
发布 ApplicationStartedEvent .
-
调用
ApplicationRunner#run()和CommandLineRunner#run(). -
发布 ApplicationReadyEvent .
-
发布 AvailabilityChangeEvent , 修改当前应用的状态为
ACCEPTING_TRAFFIC.
4. Spring Boot WebMvc 自动装配流程
-
ServletWebServerFactoryAutoConfiguration: 根据项目的依赖创建ServletWebServerFactory, 用来在Spring的ApplicationContextrefresh的时候创建一个WebServer, 并注册一些BeanPostProcessor用来定制化WebServer. -
DispatcherServletAutoConfiguration: 注册DispatcherServlet. -
WebMvcAutoConfiguration: 注册一些 SpringMVC 的组件, 如ViewResolver,ViewResolver,RequestMappingHandler,RequestMappingHandlerMapping,Validator,ExceptionHandlerExceptionResolver等.
5. Spring IoC
5.1. 从外部导入Bean的方式
-
@Import直接导入Bean类. -
@Import导入@Configuration类. -
@Import导入ImportSelector接口的实现类. -
@Import导入ImportBeanDefinitionRegistrar接口的实现类.
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注册流程
-
解析Configuration类的
@EnableAspectJAutoProxy注解, 注册AnnotationAwareAspectJAutoProxyCreator. -
postProcessBeforeInstantiation时扫描所有的Aspect, 标记出所有需要被aop的bean. -
postProcessAfterInitialization时创建代理对象.-
根据
AopUtils.findAdvisorsThatCanApply找到每个bean的advisor. -
使用
CGLIB生成代理类, 使用sun.reflect.ReflectionFactory创建代理对象.
-
7. Spring TX
7.1. Spring Transaction切面注册流程
-
解析Configuration类的
@EnableTransactionManagement注解, 注册AutoProxyRegistrar, ProxyTransactionManagementConfiguration. -
导入Configuration类
ProxyTransactionManagementConfiguration, 注册以下bean:-
transactionalEventListenerFactory: 处理事件
-
transactionAttributeSource: 定义advisor的pointcut
-
transactionInterceptor: 事务advice
-
transactionAdvisor: 事务advisor
-
-
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属性配置优先级
-
Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
-
@TestPropertySource annotations on your tests.
-
@SpringBootTest#properties annotation attribute on your tests.
-
Command line arguments.
-
Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
-
ServletConfig init parameters.
-
ServletContext init parameters.
-
JNDI attributes from java:comp/env.
-
Java System properties (System.getProperties()).
-
OS environment variables.
-
A RandomValuePropertySource that has properties only in random.*.
-
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
-
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
-
Application properties outside of your packaged jar (application.properties and YAML variants).
-
Application properties packaged inside your jar (application.properties and YAML variants).
-
@PropertySource annotations on your @Configuration classes.
-
Default properties (specified by setting SpringApplication.setDefaultProperties).