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/applicationStartup
Bean.
-
-
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的ApplicationContext
refresh的时候创建一个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).