Spring 最重要的概念是 IOC 和 AOP,其中IOC又是Spring中的根基:
创建IOC容器 初始化Bean(Annotation 和 XML)
Annotation常用,本文主要记录基于注解方式的spring源码 基于spring-5.2.14
1、实例化 AnnotationConfigApplicationContext
源码
// 加载spring上下文
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//1.无参构造 调用父类GenericApplicationContext的构造函数
//this.beanFactory = new DefaultListableBeanFactory();
//2.本类构造 reader scanner 实际不使用 为了提供context.scan()方法使用
//reader 把传入的类进行注册,这里有两个情况
// 1.传入传统的配置类可以有多个@Configuration注解的配置类
//2.@Component,@Import,@ImportResouce,@Service, @ComponentScan
this();
//componentClasses主配置类,不在是普通的Bean 源码中Full 其它类Lite
register(componentClasses);
refresh();
}
2、 实例化 DefaultListableBeanFactory
1.1 this方法() 父类空构造方法 new DefaultListableBeanFactory()
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
DefaultListableBeanFactory 类图
1.2 子类无参构造方法
//1.2子类无参构造
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
//scanner 此处仅仅只是为了供外部手动调用scan()方法 执行doScan();
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
3、实例化建BeanDefinition读取器 new AnnotatedBeanDefinitionReader(this)
1. 注册内置BeanPostProcessor
2. 注册相关的BeanDefinition
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
//片段 registerAnnotationConfigProcessors(registry, null); 调用方法返回set
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
...
1.判断容器中是否已经存在了ConfigurationClassPostProcessor Bean
2. 如果不存在(当然这里肯定是不存在的),就通过RootBeanDefinition的构造方法获得
3. ConfigurationClassPostProcessor的BeanDefinition,RootBeanDefinition是BeanDefinition的子类
4. 执行registerPostProcessor方法,registerPostProcessor方法内部就是注册Bean,当然这里注册 其他Bean也是一样的流程。
BeanDefinition
- BeanMetadataElement接口:BeanDefinition元数据,返回该Bean的来源
- AttributeAccessor接口:提供对BeanDefinition属性操作能力
它是用来描述Bean的,里面存放着关于Bean的一系列信息,比如Bean的作用域,Bean所对应的Class,是 否懒加载,是否Primary等等,这个BeanDefinition也相当重要。
registerPostProcessor()方法
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
这方法为BeanDefinition设置了一个Role,ROLE_INFRASTRUCTURE代表这是spring内部的,并非用户定 义的,然后又调用了registerBeanDefinition方法,再点进去,Oh No,你会发现它是一个接口,没办法直接点进去了,首先要知道registry实现类是什么,那么它的实现是什么呢?
答案是 DefaultListableBeanFactory:
//@cjw beanDefinitionMap是Map<String, BeanDefinition>,这里就是把beanName作为key 推到map里面
this.beanDefinitionMap.put(beanName, beanDefinition);
//@cjw beanDefinitionNames就是一个List<String>,这里就是把beanName放到List中去
this.beanDefinitionNames.add(beanName);
从这里可以看出DefaultListableBeanFactory就是我们所说的容器了,里面放着beanDefinitionMap, beanDefinitionNames,beanDefinitionMap是一个hashMap,beanName作为Key,beanDefinition作 为Value,beanDefinitionNames是一个集合,里面存放了beanName。
DefaultListableBeanFactory中的beanDefinitionMap,beanDefinitionNames也是相当重要的, 这里仅仅是注册,可以简单的理解为把一些原料放入工厂,工厂还没有真正的去生产。
上面已经介绍过,这里会一连串注册好几个Bean,在这其中最重要的一个Bean(没有之一)
就是 BeanDefinitionRegistryPostProcessor Bean。
ConfigurationClassPostProcessor实现BeanDefinitionRegistryPostProcessor接口, BeanDefinitionRegistryPostProcessor接口又扩展了BeanFactoryPostProcessor接口,
BeanFactoryPostProcessor是Spring的扩展点之一,ConfigurationClassPostProcessor是Spring极为重要的一个类。
除了注册了ConfigurationClassPostProcessor,还注册了其他Bean,
- ConfigurationClassPostProcessor.class
- AutowiredAnnotationBeanPostProcessor.class
- CommonAnnotationBeanPostProcessor.class
- EventListenerMethodProcessor.class
- DefaultEventListenerFactory.class
- JPA等
其他Bean也都实现了其他接口,比如BeanPostProcessor等。
BeanPostProcessor接口也是Spring的扩展点之一。
至此,实例化AnnotatedBeanDefinitionReader reader分析完毕。
4、创建BeanDefinition扫描器:ClassPathBeanDefinitionScanner
由于常规使用方式是不会用到AnnotationConfigApplicationContext里面的scanner的,这里的scanner 仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法。所以这里就不看 scanner是如何被实例化的了。
5、注册配置类为BeanDefinition: register(annotatedClasses)
register(componentClasses);
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//@cjw AnnotatedGenericBeanDefinition可以理解为一种数据结构,是用来描述Bean的,这里的作用就是把传入的标记了注解的类
//@cjw 转为AnnotatedGenericBeanDefinition数据结构,里面有一个getMetadata方法,可以拿到类上的注解
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//@cjw 判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
//解析bean的作用域,如果没有设置的话,默认为单例
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Descri ption
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//限定符处理,不是特指@Qualifier注解,也有可能是Primary,或者是Lazy,或者是其他(理论上是任何注解,这里没有判 断注解的有效性),如果我们在外面,以类似这种
// AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplic ationContext(Appconfig.class);常规方式去初始化spring,
// qualifiers永远都是空的,包括上面的name和instanceSupplier都是同样的道理
// 但是spring提供了其他方式去注册bean,就可能会传入了
if (qualifiers != null) {
//可以传入qualifier数组,所以需要循环处理
for (Class<? extends Annotation> qualifier : qualifiers) {
//Primary注解优先
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
//Lazy注解
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
//其他,AnnotatedGenericBeanDefinition有个Map<String,AutowireCandidateQualifier>属性,直接push进去
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
//这个方法用处不大,就是把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册,
// DefaultListableBeanFactory维护着一系列信息,比如beanDefinitionNames,beanDefinitionMap
// beanDefinitionNames是一个List<String>,用来保存beanName
// beanDefinitionMap是一个Map,用来保存beanName和beanDefinition
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
在这里又要说明下,以常规方式去注册配置类,此方法中除了第一个参数,其他参数都是默认值。
- 通过AnnotatedGenericBeanDefinition的构造方法,获得配置类的BeanDefinition,这里是不是似曾相识,在注册ConfigurationClassPostProcessor类的时候,也是通过构造方法去获得 BeanDefinition的,只不过当时是通过RootBeanDefinition去获得,现在是通过 AnnotatedGenericBeanDefinition去获得。
- 判断需不需要跳过注册,Spring中有一个@Condition注解,如果不满足条件,就会跳过这个类的 注册。
- 然后是解析作用域,如果没有设置的话,默认为单例。
- 获得BeanName。
- 解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary, DependsOn,Role,Description。
- 限定符处理,不是特指@Qualifier注解,也有可能是Primary,或者是Lazy,或者是其他(理论上 是任何注解,这里没有判断注解的有效性)。
- 把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中(这个不是很重 要,可以简单的理解为方便传参)。
- 注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册:
没错,在上面注册Spring内置的Bean的时候,已经解析过这个方法了,这里就不重复了,此时,让我们再观察下beanDefinitionMap beanDefinitionNames两个变量,除了Spring内置的Bean,还有我们传进来的Bean,这里的Bean当然就 是我们的配置类了
注册配置类解析完毕
————————————————————————————————————————
哈哈!原来是这个吊样子,层层剥开,来继续!
6.refresh()
Spring到现在还没有进行扫描,只是实例化了一个工厂,注册了一些内置的Bean和我们传进去的配置类,那在哪里进行牛B的IOC勒?
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//@cjw 刷新预处理,和主流程关系不大,就是保存了容器的启动时间,启动标志等
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//@cjw 和主流程关系也不大,最终获得了DefaultListableBeanFactory,
// DefaultListableBeanFactory实现了ConfigurableListableBeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//还是一些准备工作,添加了两个后置处理器:ApplicationContextAwareProcessor,ApplicationListenerDetector
// 还设置了 忽略自动装配 和 允许自动装配 的接口,如果不存在某个bean的时候,spring就自动注册singleton bean
// 还设置了bean表达式解析器 等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//空方法,没用?
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//执行自定义的BeanFactoryProcessor和内置的BeanFactoryProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化消息
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//@cjw 实例化所有剩余非(懒加载) 单例bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
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();
}
}
}
6.1 prepareRefresh
从命名来看,就知道这个方法主要做了一些刷新前的准备工作,和主流程关系不大,主要是保存了容器的启动时间,启动标志等。
6.1 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
这个方法和主流程关系也不是很大,可以简单的认为,就是把beanFactory取出来而已。XML模式下会在这里读取BeanDefinition
6.3 prepareBeanFactory
还是一些准备工作,添加了两个后置处理器:ApplicationContextAwareProcessor,ApplicationListenerDetector
还设置了 忽略自动装配 和 允许自动装配 的接口,如果不存在某个bean的时候,spring就自动注册singleton bean
主要做了如下的操作:
- 设置了一个类加载器
- 设置了bean表达式解析器
- 添加了属性编辑器的支持
- 添加了一个后置处理器:ApplicationContextAwareProcessor,此后置处理器实现了BeanPostProcessor接口
- 设置了一些忽略自动装配的接口
- 设置了一些允许自动装配的接口,并且进行了赋值操作 7. 在容器中还没有XX的bean的时候,帮我们注册beanName为XX的singleton bean
6.4 postProcessBeanFactory(beanFactory) 空 or 预留?
越来越懵,到底是怎么做的,怎么感觉一直没到重点?
6.5 invokeBeanFactoryPostProcessors(beanFactory)
调用所有Bean工厂的后置处理器(创世纪类)执行Bean工厂后置处理器
解析配置类 - 把业务Bean @compent@Bean@import 等一些组件类全部解析注册到BeanDefinitionMap里面
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// @cjw 重点代码终于来了,可以说 这句代码是目前为止最重要,也是内容最多的代码了,我们有必要好好分析下:
//getBeanFactoryPostProcessors()这个方法参数真是坑,第一次看到这里的时候,愣住了,总觉得获得的永远都是空的集合?
// 后来才知道spring允许我们手动添加BeanFactoryPostProcessor
// 即:annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX);
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
点进去!!! 最复杂的方法!
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
//@cjw beanFactory是DefaultListableBeanFactory,是BeanDefinitionRegistry的实现类,所以肯定满足if
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//regularPostProcessors 常规PostProcessors用来存放BeanFactoryPostProcessor,
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//registryProcessors 用来存放BeanDefinitionRegistryPostProcessor
//BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor 带注册
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 循环传进来的beanFactoryPostProcessors,正常情况下,beanFactoryPostProcessors肯定没有数据
// 因为beanFactoryPostProcessors是获得手动添加的,而不是spring扫描的
// 只有手动调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)才会有数据
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 扩展了BeanFactoryPostProcessor,所以这里先要判断是不是BeanDefinitionRegistryPostProcessor
// 是的话,直接执行postProcessBeanDefinitionRegistry方法,然后把对象装到registryProcessors里面去
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
//不是的话,就装到regularPostProcessors
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// @cjw 不在在这里初始化FactroyBeans,我们要保障常规的Bean在未初始化状态,便于让bean工厂的后置处理器来处理他们
// 在实现PriorityOrdered、Ordered和rest的BeanDefinitionRegistryPostProcessor之间进行分离。
// @cjw 一个临时变量,用来装载BeanDefinitionRegistryPostProcessor
// BeanDefinitionRegistry继承了PostProcessorBeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//@cjw todo step 1 首先看是否实现 PriorityOrdered
//获得实现BeanDefinitionRegistryPostProcessor接口的类的BeanName:
// org.springframework.context.annotation.internalConfigurationAnnotationProcessor
// 并且装入数组postProcessorNames,我理解一般情况下,只会找到一个
// 为什么我自己创建了一个实现BeanDefinitionRegistryPostProcessor接口的类,也打上了@Component注解,配置类也加上了@Component注解,但是这里却没有拿到
// 因为直到这一步,Spring还没有去扫描,扫描是在ConfigurationClassPostProcessor类中完成的,也就是下面的第一个
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//获得ConfigurationClassPostProcessor类,并且放到currentRegistryProcessors
//ConfigurationClassPostProcessor是很重要的一个类,它实现了BeanDefinitionRegistryPostProcessor接口
//BeanDefinitionRegistryPostProcessor接口又实现了BeanFactoryPostProcessor接口
//ConfigurationClassPostProcessor是极其重要的类 里面执行了扫描Bean,Import,ImportResouce等各种操作 用来处理配置类(有两种情况 一种是传统意义上的配置类,一种是普通的bean)的各种逻辑
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//把name放到processedBeans,后续会根据这个集合来判断处理器是否已经被执行过了
processedBeans.add(ppName);
}
}
//处理排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合并Processors,为什么要合并,因为registryProcessors是装载BeanDefinitionRegistryPostProcessor的
//一开始的时候,spring只会执行BeanDefinitionRegistryPostProcessor独有的方法
//而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor的方法
//所以这里需要把处理器放入一个集合中,后续统一执行父类的方法
registryProcessors.addAll(currentRegistryProcessors);
//@cjw ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
//@cjw Spring热插拔的体现,像ConfigurationClassPostProcessor就相当于一个组件,Spring很多事情就是交给组件去管理
//如果不想用这个组件,直接把注册组件的那一步去掉就可以
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//因为currentRegistryProcessors是一个临时变量,所以需要清除
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
//@cjw todo 再次根据BeanDefinitionRegistryPostProcessor获得BeanName,看这个BeanName是否已经被执行过了,有没有实现O rdered接口
// 如果没有被执行过,也实现了Ordered接口的话,把对象推送到currentRegistryProcessors,名称推送到processed Beans
// 如果没有实现Ordered接口的话,这里不把数据加到currentRegistryProcessors,processedBeans中,后续再做处理
// 这里才可以获得我们定义的实现了BeanDefinitionRegistryPostProcessor的Bean
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//处理排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合并Processors
registryProcessors.addAll(currentRegistryProcessors);
//执行我们自定义的BeanDefinitionRegistryPostProcessor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空临时变量
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
//step3 todo 最后,调用所有其他BeanDefinitionRegistryPostProcessor,直到不再出现其他BeanDefinitionRegistryPostProcessor
//上面的代码是执行了实现了Ordered接口的BeanDefinitionRegistryPostProcessor,
//下面的代码就是执行没有实现Ordered接口的BeanDefinitionRegistryPostProcessor
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//registryProcessors集合装载BeanDefinitionRegistryPostProcessor
// 上面的代码是执行子类独有的方法,这里需要再把父类的方法也执行一次
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//regularPostProcessors装载BeanFactoryPostProcessor,执行BeanFactoryPostProcessor的方法
//但是regularPostProcessors一般情况下,是不会有数据的,只有在外面手动添加BeanFactoryPostProcessor,才会有数据
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
//找到BeanFactoryPostProcessor实现类的BeanName数组
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//循环BeanName数组
for (String ppName : postProcessorNames) {
//如果这个Bean被执行过了,跳过
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
//如果实现了PriorityOrdered接口,加入到priorityOrderedPostProcessors
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
//如果实现了Ordered接口,加入到orderedPostProcessorNames
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
//如果既没有实现PriorityOrdered,也没有实现Ordered。加入到nonOrderedPostProcessorNames
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
//step1 todo 排序处理priorityOrderedPostProcessors,即实现了PriorityOrdered接口的BeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//执行priorityOrderedPostProcessors
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
//step2 todo 执行实现了Ordered接口的BeanFactoryPostProcessor
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// step 3 todo 执行既没有实现PriorityOrdered接口,也没有实现Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
首先判断beanFactory是不是BeanDefinitionRegistry的实例,当然肯定是的,然后执行如下操作:
- 定义了一个Set,装载BeanName,后面会根据这个Set,来判断后置处理器是否被执行过了。
- 定义了两个List,一个是regularPostProcessors,用来装载BeanFactoryPostProcessor,一个是registryProcessors用来装载 BeanDefinitionRegistryPostProcessor,其中
BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor。
BeanDefinitionRegistryPostProcessor有两个方法,一个是独有的postProcessBeanDefinitionRegistry方法,一个是父类的 postProcessBeanFactory方法。 - 循环传进来的beanFactoryPostProcessors,上面已经解释过了,一般情况下,这里永远都是空的,只有手动add beanFactoryPostProcessor,这里才会有数据。我们假设beanFactoryPostProcessors有数据,进入循环,判断postProcessor是不是BeanDefinitionRegistryPostProcessor,因为BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor, 所以这里先要判断是不是BeanDefinitionRegistryPostProcessor,是的话,执行postProcessBeanDefinitionRegistry方法,然后把对象装到registryProcessors里面去,不是的话,就装到regularPostProcessors。
- 定义了一个临时变量:currentRegistryProcessors,用来装载BeanDefinitionRegistryPostProcessor。
- getBeanNamesForType,顾名思义,是根据类型查到BeanNames,这里有一点需要注意,就是去哪里找,点开这个方法的 话,就知道是循环beanDefinitionNames去找,这个方法以后也会经常看到。这里传了 BeanDefinitionRegistryPostProcessor.class,就是找到类型为BeanDefinitionRegistryPostProcessor的后置处理器,并且赋值 给postProcessorNames。一般情况下,只会找到一个,就org.springframework.context.annotation.internalConfigurationAnnotationProcessor,也就是 ConfigurationAnnotationProcessor。这个后置处理器在上一节中已经说明过了,十分重要。这里有一个问题,为什么我自己写了 个类,实现了BeanDefinitionRegistryPostProcessor接口,也打上了@Component注解,但是这里没有获得,因为直到这一步, Spring还没有完成扫描,扫描是在ConfigurationClassPostProcessor类中完成的,也就是下面第一个 invokeBeanDefinitionRegistryPostProcessors方法。
- 循环postProcessorNames,其实也就是org.springframework.context.annotation.internalConfigurationAnnotationProcessor,判断此后置处理器是否实现了 PriorityOrdered接口(ConfigurationAnnotationProcessor也实现了PriorityOrdered接口), 如果实现了,把它添加到currentRegistryProcessors这个临时变量中,再放入processedBeans,代表这个后置处理已经被处理过了。当 然现在还没有处理,但是马上就要处理了。。。
- 进行排序,PriorityOrdered是一个排序接口,如果实现了它,就说明此后置处理器是有顺序的,所以需要排序。当然目前这里只 有一个后置处理器,就是ConfigurationClassPostProcessor。
- 把currentRegistryProcessors合并到registryProcessors,为什么需要合并?因为一开始spring只会执行 BeanDefinitionRegistryPostProcessor独有的方法,而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即 BeanFactoryProcessor接口中的方法,所以需要把这些后置处理器放入一个集合中,后续统一执行BeanFactoryProcessor接口中 的方法。当然目前这里只有一个后置处理器,就是ConfigurationClassPostProcessor。
- 可以理解为执行currentRegistryProcessors中的ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry 方法,这就是Spring设计思想的体现了,在这里体现的就是其中的热插拔,插件化开发的思想。Spring中很多东西都是交给插件去 处理的,这个后置处理器就相当于一个插件,如果不想用了,直接不添加就是了。这个方法特别重要,我们后面会详细说来。invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
- 清空currentRegistryProcessors,因为currentRegistryProcessors是一个临时变量,已经完成了目前的使命,所以需要清空, 当然后面还会用
- 再次根据BeanDefinitionRegistryPostProcessor获得BeanName,然后进行循环,看这个后置处理器是否被执行过了,如果没 有被执行过,也实现了Ordered接口的话,把此后置处理器推送到currentRegistryProcessors和processedBeans中。 这里就可以获得我们定义的,并且打上@Component注解的后置处理器了,因为Spring已经完成了扫描,但是这里需要注意的是,由于 ConfigurationClassPostProcessor在上面已经被执行过了,所以虽然可以通过getBeanNamesForType获得,但是并不会加入到 currentRegistryProcessors和processedBeans。
- 处理排序。
- 合并Processors,合并的理由和上面是一样的。
- 执行我们自定义的BeanDefinitionRegistryPostProcessor。
- 清空临时变量。
- 在上面的方法中,仅仅是执行了实现了Ordered接口的BeanDefinitionRegistryPostProcessor,这里是执行没有实现Ordered 接口的BeanDefinitionRegistryPostProcessor。
- 上面的代码是执行子类独有的方法,这里需要再把父类的方法也执行一次。
- 执行regularPostProcessors中的后置处理器的方法,需要注意的是,在一般情况下,regularPostProcessors是不会有数据 的,只有在外面手动添加BeanFactoryPostProcessor,才会有数据。
- 查找实现了BeanFactoryPostProcessor的后置处理器,并且执行后置处理器中的方法。和上面的逻辑差不多,不再详细说明。 这就是这个方法中做的主要的事情了,可以说是比较复杂的。但是逻辑还是比较清晰的,在第9步的时候,我说有一个方法会详细说来, 现在就让我们好好看看这个方法究竟做了什么吧。
第9步的重要方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
循环调用 postProcessBeanDefinitionRegistry 接口 最终执行ConfigurationClassPostProcessor的 postProcessBeanDefinitionRegistry方法,为什么是这个?因为这里就只有这个类;
processConfigBeanDefinitions(registry);
这里检查是否为配置类 并设置full和lite
// @cjw 检查配置主配置类,疑惑 没有@Configuration也可以?点进去看了下
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
进入checkConfigurationClassCandidate这里检查配置类条件
//@cjw todo 获取@Configuration 判断 注解中的 proxyBeanMethods 是否为true(默认) 是否使用cglib代理@Bean
//把有@configuration 并且 proxyBeanMethods = true的类作为主配置类 设置为full
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
//@cjw todo 如果没有@Configuration则判断 是否接口是否有@compentscan@import@compent@importResource @Bean注解的方法,如果有@Bean 给beandefinition的树设置为lite、
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}
// It's a full or lite configuration candidate... Let's determine the order value, if any.
Integer order = getOrder(metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
- 获得所有的BeanName,放入candidateNames数组。
- 循环candidateNames数组,根据beanName获得BeanDefinition,判断此BeanDefinition是否已经被处理过了。
- 判断是否是配置类,如果是的话。加入到configCandidates数组,在判断的时候,还会标记配置类属于Full配置类,还是Lite配 置类,这里会引发一连串的知识盲点:
3.1 当我们注册配置类的时候,可以不加@Configuration注解,直接使用@Component @ComponentScan @Import @ImportResource等注解,Spring把这种配置类称之为Lite配置类, 如果加了@Configuration注解,就称之为Full配置类。
3.2 如果我们注册了Lite配置类,我们getBean这个配置类,会发现它就是原本的那个配置类,如果我们注册了Full配置类,我们getBean 这个配置类,会发现它已经不是原本那个配置类了,而是已经被cgilb代理的类了。
3.3 写一个A类,其中有一个构造方法,打印出“你好”,再写一个配置类,里面有两个被@bean注解的方法,其中一个方法new了A类, 并且返回A的对象,把此方法称之为getA,第二个方法又调用了getA方法,如果配置类是Lite配置类,会发现打印了两次“你好”,也就是说A类被new了两次,如果配置类是Full配置类,会发现只打印了一次“你好”,也就是说A类只被new了一次,因为这个类被cgilb代理 了,方法已经被改写。 - 如果没有配置类直接返回。
- 处理排序。
- 解析配置类,可能是Full配置类,也有可能是Lite配置类,这个小方法是此方法的核心,稍后具体说明。
- 在第6步的时候,只是注册了部分Bean,像 @Import @Bean等,是没有被注册的,这里统一对这些进行注册。 下面是解析配置类的过程:
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
//@cjw todo 递归处理内部类
processMemberClasses(configClass, sourceClass, filter);
}
// Process any @PropertySource annotations
// 处理PropertySources 注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
//处理compentscans
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
//处理 @import
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// Process any @ImportResource annotations
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// Process individual @Bean methods
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
processInterfaces(configClass, sourceClass);
// Process superclass, if any
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
1. 递归处理内部类,一般不会使用内部类。
2. 处理@PropertySource注解,@PropertySource注解用来加载properties文件。
3. 获得ComponentScan注解具体的内容,ComponentScan注解除了最常用的basePackage之外,还有includeFilters, excludeFilters等。
4. 判断有没有被@ComponentScans标记,或者被@Condition条件带过,如果满足条件的话,进入if,进行如下操作
4.1 执行扫描操作,把扫描出来的放入set,这个方法稍后再详细说明。
4.2 循环set,判断是否是配置类,是的话,递归调用parse方法,因为被扫描出来的类,还是一个配置类,有@ComponentScans注解, 或者其中有被@Bean标记的方法 等等,所以需要再次被解析。
5. 处理@Import注解,@Import是Spring中很重要的一个注解,正是由于它的存在,让Spring非常灵活,不管是Spring内部,还 是与Spring整合的第三方技术,都大量的运用了@Import注解,@Import有三种情况,一种是Import普通类,一种是Import ImportSelector,还有一种是Import ImportBeanDefinitionRegistrar,getImports(sourceClass)是获得import的内容,返回的 是一个set,这个方法稍后再详细说明。
6. 处理@ImportResource注解。
7. 处理@Bean的方法,可以看到获得了带有@Bean的方法后,不是马上转换成BeanDefinition,而是先用一个set接收。 我们先来看4.1中的那个方法
1. 定义了一个扫描器scanner,还记不记在new AnnotationConfigApplicationContext的时候,会调用 AnnotationConfigApplicationContext的构造方法,构造方法里面有一句 this.scanner = new ClassPathBeanDefinitionScanner(this);当时说这个对象不重要,这里就是证明了。常规用法中,实际上执行扫描的只会是这里的 scanner对象。
2. 处理includeFilters,就是把规则添加到scanner。
3. 处理excludeFilters,就是把规则添加到scanner。
4. 解析basePackages,获得需要扫描哪些包。
5. 添加一个默认的排除规则:排除自身。
6. 执行扫描,稍后详细说明。 这里需要做一个补充说明,添加规则的时候,只是把具体的规则放入规则类的集合中去,规则类是一个函数式接口,只定义了一个虚方法 的接口被称为函数式接口,函数式接口在java8的时候大放异彩,这里只是把规则方塞进去,并没有真正执行匹配规则。 我们来看看到底是怎么执行扫描的:
6.1. 把传进来的类似命名空间形式的字符串转换成类似类文件地址的形式,然后在前面加上classpath,即: com.xx=>classpath:com/xx/**/*.class。
6.2. 根据packageSearchPath,获得符合要求的文件。
6.3. 循环符合要求的文件,进一步进行判断。 最终会把符合要求的文件,转换为BeanDefinition,并且返回。
6.6-registerBeanPostProcessors(beanFactory);
实例化和注册beanFactory中扩展了BeanPostProcessor的bean。 例如: AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入) RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法) CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。
6.7-initMessageSource()
初始化国际化资源处理器. 不是主线代码忽略 initMessageSource();
6.8-initApplicationEventMulticaster()
创建事件多播器 :Spring事件监听机制
6.9-onRefresh();
模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情。
6.10-registerListeners();
注册监听器,广播early application events 事件:Spring事件监听机制
6.11-finishBeanFactoryInitialization(beanFactory);
实例化所有剩余的(非懒加载)单例 比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。 实例化的过程各种BeanPostProcessor开始起作用。
6.12 finishRefresh();
发布相对应的事件
简要流程图