Spring 启动
2022-07-27 00:38:14 0 举报
AI智能生成
Spring启动以及配置类解析
作者其他创作
大纲/内容
调用父类 GenericApplicationContext 构造器,构造一个 BeanFactory(DefaultListableBeanFactory)
调用无参构造器
注册 AnnotatedBeanDefinitionReader
注册 conditionEvaluator,用来解析 @Condition 注解
注册 BeanFactoryPostProcess 和 BeanPostProcessor
设置 beanFactory 的 OrderComparator 为 AnnotationAwareOrderComparator
设置 autowireCandidateResolver 为 ContextAnnotationAutowireCandidateResolver
注册 ConfigurationClassPostProcessor 对应的 BeanDefinition,它是一个 BeanDefinitionRegistryPostProcessor 并且实现了 PriorityOrdered
注册 AutowiredAnnotationBeanPostProcessor 对应的 BeanDefinition,它是一个InstantiationAwareBeanPostProcessorAdapter,并且实现了 MergedBeanDefinitionPostProcessor
注册 RequiredAnnotationBeanPostProcessor 对应的 BeanDefinition,它是一个InstantiationAwareBeanPostProcessorAdapter,并且实现了 MergedBeanDefinitionPostProcessor
用来处理 @Required 注解,主要用在 setter 方法上,它表示该 setter 方法的属性必须要在配置时注入值
注册 CommonAnnotationBeanPostProcessor 对应的 BeanDefinition,它是一个InitDestroyAnnotationBeanPostProcessor,并且实现了 InstantiationAwareBeanPostProcessor
注册 PersistenceAnnotationBeanPostProcessor 对应的 BeanDefinition,实现了 InstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered
处理 @PersistenceUnit 和 @PersistenceContext 注解的 BeanPostProcessor,用于注入相应的 JPA 资源 EntityManagerFactory和Enti tyManager
注册 EventListenerMethodProcessor 对应的 BeanDefinition,实现了 SmartInitializingSingleton
将被 @EventListener 注解的方法注册为 ApplicationListener 实例。
注册 DefaultEventListenerFactory 对应的 BeanDefinition,实现了 EventListenerFactory
默认的 EventListenerFactory 实现,支持 @EventListener 注释
注册 ClassPathBeanDefinitionScanner
注册 BeanDefinitionRegistry 为当前容器(AnnotationConfigApplicationContext)
注册默认过滤器
设置 environment
设置 resourceLoader
用 reader 注册 AppConfig 为 BeanDefinition,类型为 AnnotatedGenericBeanDefinition
refresh 方法
prepareRefresh()
记录启动时间
如果子类重写 initPropertySources(),可以设置变量到 Environment
校验必须环境变量有值
context.getEnvironment().setRequiredProperties("aaa")
obtainFreshBeanFactory()
判断能否刷新,如果可以则刷新容器并返回一个 BeanFactory
AbstractRefreshableApplicationContext 支持重复刷新,先销毁再重新生成
即 AnnotationConfigWebApplicationContext 支持重复刷新
GenericApplicationContext 不支持重复刷新
即 AnnotationConfigApplicationContext 支持重复刷新
prepareBeanFactory()
设置 beanFactory 的类加载器
设置 Spel 解析器为 StandardBeanExpressionResolver
注册 ResourceEditorRegistrar
注册一些默认的类型转换器
将 ApplicationContextAwareProcessor 注册为 BeanPostProcessor (实例对象)
处理 EnvironmentAware、EmbeddedValueResolverAware 等 Aware 回调
添加 ignoredDependencyInterfaces
如果一个属性的 set 方法在 ignoredDependencyInterfaces 中被定义了,则该属性不会被自动注入
(Spring 自带注入 byType、byName 会忽略掉这些接口提供的set方法,@Autowired 还是会注入)
(Spring 自带注入 byType、byName 会忽略掉这些接口提供的set方法,@Autowired 还是会注入)
添加 registerResolvableDependency
类型和对象之间的对应关系,在 byType 进行依赖注入时,会先从这个属性中根据类型找 bean
将 ApplicationListenerDetector 注册为 BeanPostProcessor(实例对象)
ApplicationListenerDetector 负责把 ApplicationListener 类型的 Bean 注册到 ApplicationContext 中
将 LoadTimeWeaverAwareProcessor 注册为 BeanPostProcessor(实例对象)
来判断某个 Bean 是不是实现了 LoadTimeWeaverAware 接口,如果实现了则把 ApplicationContext 中的 loadTimeWeaver 回调 setLoadTimeWeaver 方法设置给该 Bean。
Aspectj 本身是通过编译期进行代理的,在 spring 中就跟 loadTimeWeaver 有关
添加一些单例 Bean
environment <---> StandardEnvironment
systemProperties <---> System.getProperties()
systemEnvironment <---> System.getenv()
postProcessBeanFactory(beanFactory)
在标准初始化之后修改应用程序上下文的内部bean工厂。这允许在特定的ApplicationContext实现中注册特殊的BeanPostProcessors等
invokeBeanFactoryPostProcessors()
执行 BeanFactoryPostProcessors
执行通过 ApplicationContext 添加进来的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry() 方法
一般为空
执行 BeanFactory 中实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry() 方法
会拿到 ConfigurationClassPostProcessor
在此处会完成扫描,会扫描到自定义的 BeanFactoryPostProcessor
在此处会完成扫描,会扫描到自定义的 BeanFactoryPostProcessor
遍历所有的 BeanDefinition,找到配置类的 BeanDefinition
判断是不是@Bean 定义的配置类
加载AnnotationMetadata(不一定要加载这个类)
获取@Configuration注解信息
加了 @Configuration 并且 proxyBeanMethods 不为 false ( true or null ),则为 Full 配置类
加了 @Configuration 并且 proxyBeanMethods 为 false ,则为 Lite 配置类
或没有 @Configuration 但是加了 @Component、@ComponentScan、@Import、@ImportResource 就是 Lite 配置类
或没有 @Configuration 但是存在 @Bean 注解的方法就是 Lite 配置类
或没有 @Configuration 但是加了 @Component、@ComponentScan、@Import、@ImportResource 就是 Lite 配置类
或没有 @Configuration 但是存在 @Bean 注解的方法就是 Lite 配置类
根据 @Order 设置排序值
通过 @Order 进行排序,值越小越靠前
预先往单例池中添加 BeanNameGenerator 类的 Bean
用来生成扫描得到的 Bean 和 Import 导入 bean 的 BeanName
用来生成扫描得到的 Bean 和 Import 导入 bean 的 BeanName
递归解析配置类
(有可能通过解析一个配置类,得到其他的配置类,比如 带有@Import的配置类)
(有可能通过解析一个配置类,得到其他的配置类,比如 带有@Import的配置类)
解析配置类,会把每个 BeanDefinition 先封装成 ConfigurationClass
(在这个过程中会进行扫描、导入等步骤,从而会找到其他的 ConfigurationClass)
(ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>))
(在这个过程中会进行扫描、导入等步骤,从而会找到其他的 ConfigurationClass)
(ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>))
循环解析所有配置类 BeanDefinition 所对应的类
获取元数据信息
封装成 ConfigurationClass
处理 ConfigurationClass
(processConfigurationClass(ConfigurationClass configClass))
(processConfigurationClass(ConfigurationClass configClass))
解析 @Conditional 条件注解,判断是否需要解析
判断是否已经导入过了
如果已经导入过了并且当前是通过 @Import 导入的
如果已经导入的是通过 @Import 导入的,则合并 配置类
如果已经导入的不是通过 @Import 导入的,跳过当前配置类的导入
如果已经导入过了并且当前不是通过 @Import 导入,则重新导入
递归解析配置类及父类
(doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass))
(处理@PropertySources、@ComponentScans、@Import、@ImportResource、配置类中@Bean方法)
(doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass))
(处理@PropertySources、@ComponentScans、@Import、@ImportResource、配置类中@Bean方法)
解析内部类中的配置类
解析 @PropertySources 注解
(封装为 PropertySource添加到 Environment)
(封装为 PropertySource添加到 Environment)
解析 @ComponentScans 注解
(会进行扫描,得到的 BeanDefinition 注册到 Spring 容器中
, 并且会检查是不是配置类并进行解析)
(会进行扫描,得到的 BeanDefinition 注册到 Spring 容器中
, 并且会检查是不是配置类并进行解析)
解析 @ComponentScans 属性值
扫描指定路径
1. ClassPathScanningCandidateComponentProvider.findCandidateComponents( )
扫描某个包路径,并得到 BeanDefinition 的 Set 集合。
扫描某个包路径,并得到 BeanDefinition 的 Set 集合。
如果筛选通过,那么就表示扫描到了一个 Bean,将 ScannedGenericBeanDefinition 加入结果集
将指定的文件通过 ASM 技术进行加载
检查是否被排除或者是否包含
封装成 ScannedGenericBeanDefinition
判断是不是顶级类(独立类或者静态内部类)、是不是接口或抽象类(除非标记 @lookup)
2. 遍历每个 BeanDefinition
3. 设置作用域 setScope( )
4. 调用 AnnotationBeanNameGenerator 生成 beanName
5. 设置 BeanDefinition 对象的默认值 LazyInit、AutowireMode、tInitMethodName 等
6. 解析 @lazy、@Primary、@DependsOn、@Role、@Description 等注解并赋值给 BeanDefinition 对应的属性
7. 检查容器中是否存在该 BeanName,返回 false 不会注册进去(重复扫描),如果冲突直接抛出异常
8. BeanDefinition 注册进容器,结束扫描
检查扫描出来的 BeanDefinition 是不是配置类,如果是的话进行解析
解析 @Import
ConfigurationClassParser#processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports)
ConfigurationClassParser#processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports)
导入 ImportSelector
如果导入的是普通 ImportSelector,那么会将返回的类再次调用 processImports()
如果实现了 DeferredImportSelector ,那么暂时不会处理,会在解析完所有当前这轮配置类后进行导入
如果导入的是 ImportDeanDefinitionRegistrar,那么暂时不会处理,会在解析完所有当前这轮配置类后解析成 DeanDefinitionRegistrar
导入普通类,直接作为配置类处理
(asConfigClass 方法不仅会将 candidate 生成一个 ConfigurationClass,还会记录一下 candidate 是被谁导入的)
(asConfigClass 方法不仅会将 candidate 生成一个 ConfigurationClass,还会记录一下 candidate 是被谁导入的)
解析 @ImportResource
(并未直接解析配置文件,而是加入属性 importedResources)
(并未直接解析配置文件,而是加入属性 importedResources)
解析@Bean方法
(并没有真正处理,只是暂时找出来 加入属性 beanMethods)
(并没有真正处理,只是暂时找出来 加入属性 beanMethods)
解析实现接口中被 @Bean 注解的默认方法
(只是加入 beanMethods 属性)
(只是加入 beanMethods 属性)
记录已经解析的配置类
当前一轮配置类解析完之后处理 DeferredImportSelectors
验证配置类
(必须是非 final并且可重写(适配CGLB))
(必须是非 final并且可重写(适配CGLB))
把所有 ConfigurationClass 加载成 BeanDefinition
(处理 @ImportResource 以及 ImportBeanDefinitionRegistrar)
(处理 @ImportResource 以及 ImportBeanDefinitionRegistrar)
执行 BeanFactory 中实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry() 方法
每次都从容器中重新获取,因为前一步有可能注册新的
执行 BeanFactory 中其他的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry() 方法
执行上面所有的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory() 方法
ConfigurationClassPostProcessor
将 full 配置类生成代理并加入 BeanDefinition
将 full 配置类生成代理并加入 BeanDefinition
生成的代理对象会注入拦截器
代理对象在执行被 @Bean 修饰的方法式时,会从 Spring 容器中获取对象
执行通过 ApplicationContext 添加进来的 BeanFactoryPostProcessor 的 postProcessBeanFactory() 方法
执行 BeanFactory 中实现了 PriorityOrdered 接口的 BeanFactoryPostProcessor 的 postProcessBeanFactory() 方法
执行 BeanFactory 中实现了 Ordered 接口的 BeanFactoryPostProcessor 的 postProcessBeanFactory() 方法
执行 BeanFactory 中其他的 BeanFactoryPostProcessor 的 postProcessBeanFactory() 方法
添加 BeanPostProcessor:loadTimeWeaver
registerBeanPostProcessors()
将注册以及扫描得到的 BeanPostProcessors 实例化并排序,然后添加到 BeanFactory 的 BeanPostProcessors 属性中去
重新添加一个 ApplicationListenerDetector 对象(之前其实就添加了过,这里是为了把 ApplicationListenerDetector 移动到最后)
initMessageSource()
设置 ApplicationContext 的 MessageSource,要么是用户设置的,要么是 DelegatingMessageSource
initApplicationEventMulticaster()
设置 ApplicationContext 的 applicationEventMulticaster,要么是用户设置的,要么是 SimpleApplicationEventMulticaster。
SimpleApplicationEventMulticaster 将事件广播给监听器,默认单线程串行执行,可设置线程池
onRefresh()
提供给 AbstractApplicationContex t的子类进行扩展
registerListeners()
从 BeanFactory 中获取 ApplicationListener 类型的 beanName,然后添加到 ApplicationContext 中的事件广播器 applicationEventMulticaster 中去
finishBeanFactoryInitialization()
设置 ConversionService
设置默认的占位符解析器 ${xxx}
实例化加载时织入
实例化非懒加载的单例 Bean
finishRefresh()
设置 lifecycleProcessor,默认为 DefaultLifecycleProcessor
调用 LifecycleBean 的 start()
发布 ContextRefreshedEvent 事件
0 条评论
下一页