1. AnnotationConfigApplicationContext 的 reader 和 scanner
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
// 注册解析这个 Bean 为 BeanDefinition
register(componentClasses);
// 刷新容器,这个时候才是对这个 BeanDefinition 进行进一步解析
refresh();
}
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
内部逻辑先暂略,简略描述
/**
* 注解 Class 读取器/处理器,在构造函数中创建
* AnnotatedBeanDefinitionReader 被实例化时已经向容器注入了部分 BeanDefinition
* 区分 BeanPostProcessor 和 BeanFactoryPostProcessor
*
* 从其提供的 API 来看,大致就是将一个 Class 解析为 BeanDefinition 放入 BeanFactory
*/
private final AnnotatedBeanDefinitionReader reader;
/**
* 类路径扫描器,可以进行包扫描,然后呢?
* 这个在实例化时就没有创建预先注入 BeanDefinition 了
*/
private final ClassPathBeanDefinitionScanner scanner;
2. register
利用 reader 解析传入的 Class 并进行基础的解析转换为 BeanDefinition
并将这个 BeanDefinition
注入 BeanFactory
org.springframework.context.annotation.AnnotationConfigApplicationContext#register
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
// 使用注解BD读取器去注册/处理这个 Bean
this.reader.register(componentClasses);
}
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#register
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// Generic [dʒəˈnerɪk],通用的,adj. (药物或商品)无专利的,未注册的
// 这个应该是用于封装一个(可能)使用了注解的Bean,内部会进行解析注解信息并封装
// 封装为 BeanDefinition
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 这个应该是涉及到条件注入等的
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
// 下面解析注解并设置 BeanDefinition,从上面的 new AnnotatedGenericBeanDefinition 可以看到只是将解析的注解封装为一个属性,具体
// 如何处理这些注解并设置 BeanDefinition 则由后面的进行解析
// 这个是不由 Spring 实例化,表示由这个 supplier 进行实例化,在哪里有使用呢?
abd.setInstanceSupplier(supplier);
// 解析 Bean 的生命周期 Scope,这里解析器也有几种,Spring 自己的注解 @Scope 解析,javax.inject.Scope 的解析,略后者
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// beanName 生成,如何自定义 BeanName 生成器?
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 通用注解解析,那么区分需要外部处理的和需要工具类处理的标准/条件是什么?是是否可以直接进行简单处理吗(如上面的还需要解析器啥的)
// @Lazy、@Primary、@DependsOn、@Role、@Description,后面两个都没使用过
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
// 为什么还会有额外的参数传入呢
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
// 定制处理,customizers 这种可以定制处理的(或命名)的在 Spring 中还挺多的
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 问题:这里的 beanName 为什么不可以设计到 BeanDefinition 里面呢,还需要封装一层
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 如果当前类要被代理,代理的模式(JDK、CGLIB)
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册 BD 到容器,没有进一步处理
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
3. rerfresh.BeanFactoryPostProcessor 执行
上面已经将配置类给转换为 BeanDefinition 注入容器了,接下来还需要解析这个 BeanDefinition
BeanFactoryPostProcessor:对 BeanDefinition 进行进一步修饰和处理,一般不会再将 BeanDefinition 注入 BeanFactory
BeanDefinitionRegistryPostProcessors:BeanFactoryPostProcessor 的子接口,主要是发现 BeanDefinition 并将 BeanDefinition 注入 BeanFactory
注意上面两个接口所提供的/需要实现的方法的功能,一般不会在 BeanFactoryPostProcessor 接口提供的功能中发现 BD 和注入 BD
org.springframework.context.support.AbstractApplicationContext#refresh
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
// 暂略
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 暂略
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 内部设置了一些 BeanFactory 的属性,直接注入了一些 Bean 实例
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 暂略,这里好像 Web 进行处理了
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
// 调用 BeanFactoryPostProcessor 对 BeanDefinition 进行处理,通过对 BeanDefinition 处理可能又会发现更多的 BeanDefinition(如解析 @ComponentScan 时)
invokeBeanFactoryPostProcessors(beanFactory);
...
}
}
}
上面代码很多都略去了,现在仅先抓住主干,具体细节暂略
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 这种使用 Delegate 进行处理的方法, 是为了避免单个类太长 + 功能太多吗?单一职责?有时候一些类我会命名为 Helper
// 注意这里的 getBeanFactoryPostProcessors, 也就是我们也可以在 refresh 容器前将自定义的 BeanFactoryPostProcess add 进入 ApplicationContext
// 至于容器内部自己注册进去的那些,会在内部自己发现(因为可以从传入的 BeanFactory 中查)
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 (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
下面这个也只是大体流程,具体的 BeanFactoryPostProcessor 没有具体解析流程
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
// 下面先调用的是 BeanDefinitionRegistryPostProcessors,这个主要是发现 BeanDefinition 并将 BeanDefinition 注入 BeanFactory
// 而与其类似的(其父接口)为 BeanFactoryPostProcessor,这个主要是对 BeanDefinition 进行进一步修饰和处理,一般不会再将 BeanDefinition 注入 BeanFactory
Set<String> processedBeans = new HashSet<>();
// 这个不是 BeanFactory 继承链的,而是单独的一个接口,提供对容器 BeanDefinition 的增删查等操作
// 会有不是的场景吗,后面不是就直接调用 BeanFactoryPostProcessor 操作 BeanDefinition 了(也即不能增删等操作,仅能查询并修改 BeanDefinition)
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 注意这里就已经执行了,但是 BeanFactoryPostProcessor 接口的方法还未执行(父接口就是 BeanFactoryPostProcessor)
// 这里实际上就可以执行以下自己的 BeanDefinition 发现逻辑啊等等,MyBatis 实现了这个吗?
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 存储的实际是一已执行的,这种命名是否可以优化一下便于阅读
registryProcessors.add(registryProcessor);
}
else {
// BeanFactoryPostProcessor 类型,还未执行
regularPostProcessors.add(postProcessor);
}
}
// 注意下面执行 BeanFactory 内的 BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor,因为需要实例化才能执行,所以在这里就 getBean 了
// 包括如果我们也注入了这些类型的,那么也是在这里就被 getBean 了,还可能没经过整个生命周期,因此编写时要注意
// 下面就是处理 BeanFactory 中的,内含
// 1. 上面自定义执行后注入的
// 2. Spring 容器内部自己注入的
// 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.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 先处理 PriorityOrdered 接口的,也先执行
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 处理 Ordered 接口的
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);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 处理其他的,内部进行了 while 处理,也即在上面执行后注入的如果未执行也会在下面执行,当然在下面执行后注入的也会被执行
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 这里就是执行 BeanFactoryPostProcessor 接口的,优先级也是先执行 BeanDefinitionRegistryPostProcessor 的,顺序也是上面执行的顺序
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 这里参数传入的优先级反而靠后了
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
// 注意了,这里仅执行了参数传入的,对于 BeanFactory 内部的没有执行
// 当然同时由于 BeanFactory 类型的原因,认为是不可以向内注入 BeanDefinition 的,因此也没必要 while 关心是否有新的注入
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 下面就应该处理 BeanFactory 内部的 BeanFactoryPostProcessor 接口方法了,上面虽然执行了一些,但那是 BeanDefinitionRegistryPostProcessor 类型的(BeanFactoryPostProcessor 子接口)
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 获取 BeanFactory 内部所有的 BeanFactoryPostProcessor,注意入参传入的没有
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<>();
for (String ppName : postProcessorNames) {
// 上面已执行则略过
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
// 分类且按照顺序执行
// 问题: 为什么仅 priority 的在这里就获取了 Bean,而其他的后面才获取呢(倒不是逻辑问题,而是写的时候怎么想的)
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
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();
}