调试代码
以注解形式阐明 BeanDefinition 的收集过程, 调试代码如下:
public class AnnotationACTest {public static void main(String[] args) {
// new 一个利用上下文的时候, 会注册一些外部的 BeanFactoryPostProcessor 的 beanDefinition
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
ac.register(BeanConfig.class);
ac.refresh();}
}
BeanConfig
@Configuration
@ComponentScan("com.mfy.test.bean")
@EnableAspectJAutoProxy
public class BeanConfig {
@Bean
public User getUser(){this.getWoman();
return new User();}
@Bean("women")
public Woman getWoman(){System.out.println("测试 @Configuration 的类办法外部调用");
return new Woman();}
}
扫描包下的某一个 Bean
@Component
public class PropertyBean {
private String username;
private String password;
public String getUsername() {return username;}
public void setUsername(String username) {this.username = username;}
public String getPassword() {return password;}
public void setPassword(String password) {this.password = password;}
}
源码剖析
首先创立 ApplicationContext 对象, 创立进去的 AnnotationConfigApplicationContext 外部会持有 DefaultListableBeanFactory(实现了 BeanFactory 接口的所有办法)
public AnnotationConfigApplicationContext() {// 隐式的会调用父类的构造方法,this.beanFactory = new DefaultListableBeanFactory();
// 此处会增加外部的一些 beanDefinition, 存储到 BeanFactory 的 beanDefinitionMap
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
值得注意的是, 创立 AnnotatedBeanDefinitionReader 的过程, 会将 ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 的 beanDefinition 退出到 spring 容器中; 创立 ClassPathBeanDefinitionScanner 时, 会将 @Component 注解退出到 includeFilters.
注入 PostProcessor 的代码:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 判断 BeanFactory 中不存在此 BeanDefinition, 增加 ConfigurationClassPostProcessor
// ConfigurationClassPostProcessor 类负责解析解决所有 @Configuration 类,并将 BeanDefinition 注册到 BeanFactory 中。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));
}
// AutowiredAnnotationBeanPostProcessor 类负责解决 @Autowired
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));
}
// CommonAnnotationBeanPostProcessor 类负责解决 @Resource,@PostConstruct,@PreDestroy
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 省略了局部代码
return beanDefs;
}
注入 @Component 注解
protected void registerDefaultFilters() {
// 此处将 Component 注入, 用于前面的辨认
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
// 省略局部代码
}
通过下面的步骤, 只是实现了 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext()
这一行代码的运行.
接下来, 要将配置类 BeanConfig, 手动注入到创立进去的 AnnotationConfigApplicationContext 中, 实际上, 是委托给了 AnnotatedBeanDefinitionReader 来进行配置类的解析工作
public void register(Class<?>... componentClasses) {Assert.notEmpty(componentClasses, "At least one component class must be specified");
// 解析给定的 class 对象, 并存储到 beanDefinitionMap
this.reader.register(componentClasses);
}
this.reader.register(componentClasses)
这行代码, 会始终调用到doRegisterBean()
, 才会开始真正的逻辑解决, 其实只做了一件事, 就是生成 BeanConfig 的 BeanDefinition, 并注入到 spring 容器中.
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
// 设置单例还是原型
abd.setScope(scopeMetadata.getScopeName());
// 设置 beanName, 当传入的 name 为 null, 依照规定, 主动生成名称
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 解析局部公共的注解(@Lazy,@Primary,@DependsOn,@Role,@Description), 并将解析进去的信息填充到 beanDefinition 中
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));
}
}
}
if (customizers != null) {for (BeanDefinitionCustomizer customizer : customizers) {customizer.customize(abd);
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 将解析实现的 beanDefinition 放入 beanFactory 中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
此时代码运行完了ac.register(BeanConfig.class)
, 接下来要刷新容器, 即运行ac.refresh()
, 这个办法是所有 bean 进行实例化和初始化的外围, 须要重点剖析, 外围步骤如下:
- 获取 beanFactory
- 遍历 BeanDefinitionRegistryPostProcessor 接口的实现类, 调用 postProcessBeanDefinitionRegistry()办法, 将 BeanConfig 中 @ComponentScan 笼罩的 bean 的 beanDefinition 信息注册到 spring 容器中
- 实例化, 初始化所有非懒加载的单例 bean
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// 获取 BeanFactory, 其实是 DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置 BeanFactory 的类加载器,增加几个 BeanPostProcessor,手动注册几个非凡的 bean
prepareBeanFactory(beanFactory);
try {
// 扩大点, 能够对 beanFactory 做批改
postProcessBeanFactory(beanFactory);
// 实例化 BeanFactoryPostProcessor(new 利用上下文的时候注册的 beanDefinition)并调用, 作用是批改 beanDefinition 的信息
// 例如 internalConfigurationAnnotationProcessor, 用来解析 @Configuration 注解类管辖的 beanDefinition 信息
invokeBeanFactoryPostProcessors(beanFactory);
// 实例化各种 BeanPostProcessors, 并注册到 beanFactory 的 beanPostProcessors 属性中
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// 初始化事件播送器(给 applicationEventMulticaster 赋值)
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// 注册监听器(非 @EventListener 注解形式, 注册的是实现了 ApplicationListener 接口的类)
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();}
// 省略局部代码
}
首先, 剖析步骤 2
- 收集实现了 PriorityOrdered 接口和 BeanDefinitionRegistryPostProcessor 接口的实现类并调用 postProcessBeanDefinitionRegistry(), 其实就是调用 ConfigurationClassPostProcessor, 这个类是 spring 中的外围类, 作用是收集 @Component 注解的 Bean 信息, 解析成 BeanDefinition 注册到 spring 容器中
- 收集实现了 Ordered 接口和 BeanDefinitionRegistryPostProcessor 接口的实现类并调用 postProcessBeanDefinitionRegistry()
- 死循环收集 BeanDefinitionRegistryPostProcessor 接口的实现类 (排除了后面的) 并调用 postProcessBeanDefinitionRegistry()
- 调用后面所有 BeanDefinitionRegistryPostProcessor 接口的实现类的 postProcessBeanFactory()办法
- 收集 BeanFactoryPostProcessor 接口的实现类, 也是分成实现了 PriorityOrdered 接口,Ordered 接口和其余的三种状况, 而后调用 postProcessBeanFactory()办法
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 曾经实现调用的后置处理器汇合
Set<String> processedBeans = new HashSet<>();
// 省略局部代码
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 获取实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor 实现类, 排序之后, 按顺序调用
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);
// 目前是调用 ConfigurationClassPostProcessor, 解析“配置类”的蕴含的 bean 信息,变成 beanDefinition 存入 map 中
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 获取实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor 实现类, 排序之后, 按顺序调用
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);
currentRegistryProcessors.clear();
// 死循环获取其余所有的 BeanDefinitionRegistryPostProcessor 实现类, 排序之后, 按顺序调用
// 死循环 BeanDefinitionRegistryPostProcessor 实现类的起因是, 后面的 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);
// 遍历 BeanDefinitionRegistryPostProcessor 的实现类, 调用 postProcessBeanDefinitionRegistry()
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();}
// 遍历 BeanDefinitionRegistryPostProcessor 实现类, 调用 postProcessBeanFactory()
// 对于 ConfigurationClassPostProcessor, 生成“配置”类 (@Configuration) 的代理类
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 遍历非 BeanDefinitionRegistryPostProcessor 实现类(本人加进来的), 调用 postProcessBeanFactory(), 根本不会执行
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {// 遍历非 BeanDefinitionRegistryPostProcessor 实现类(本人加进来的), 调用 postProcessBeanFactory(), 根本不会执行
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! 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) {
// 跳过后面曾经解决过的 BeanFactoryPostProcessor 实现类
if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 通过 beanFactory 的 getBean(), 实例化 BeanFactoryPostProcessor
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);
beanFactory.clearMetadataCache();}
上面重点剖析一下 ConfigurationClassPostProcessor, 其实就是剖析 processConfigBeanDefinitions(), 看看是如何将 bean 变成 beanDefinition 注册到 spring 容器
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against" + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against" + registry);
}
this.registriesPostProcessed.add(registryId);
// 解析 @Component,@ComponentScan,@Import,@ImportResource 注解
processConfigBeanDefinitions(registry);
}
接下来, 看看 processConfigBeanDefinitions()的实现逻辑, 次要流程如下:
- 获取容器中所有曾经注册进来的 beanName, 其实此时只有一个手动注册进来的 BeanConfig, 其余的全部都是 spring 本人注册的
- 筛选出 @Configuration 注解的类, 其实就是 BeanConfig
- 创立 ConfigurationClassParser, 是个解析器, 作用是解析 @ComponentScan 注解
- 进行 parse(), 将 @ComponentScan 指定的包下所有 @Component 注解的 bean 变成 beanDefinitiion 注册到 spring 容器中, 同时对每一个 @Component 注解的 bean, 包装成 ConfigurationClass(封装了注解信息 metadata,beanName,beanMethods 和 importedResources), 注册到 ConfigurationClassParser 中的 configurationClasses 属性
- 遍历 configurationClasses 中的 ConfigurationClass, 解决 @Bean,@Import 和 @ImportResource 注解, 其中,@Bean 和 @Import 会生成 beanDefinition 注册到 spring 容器中
- 找出步骤 4 中注册进来的 beanDefinition, 判断这些 beanDefinition 是否存在 @Configuration,@ComponentScan,@Component,@ImportResource 和 @Import 注解(至于为什么没有在步骤 3 中扫描到这些 beanDefinition, 起因是这些 bean 不在 @ComponentScan 所指定的包下), 若判断为 true, 则将反复步骤 3~6
通过以上步骤之后,@ComponentScan 指定包下的 bean 都曾经变成 beanDefinition 注册到 spring 容器中了
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
// 筛选具备 @Component,@ComponentScan,@Import,@ImportResource 注解信息的 BeanDefinition
for (String beanName : candidateNames) {BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {if (logger.isDebugEnabled()) {logger.debug("Bean definition has already been processed as a configuration class:" + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {// 若是无 xml 形式配置的, 此处只会筛选出 @Configuration 注解的类(即 ac.register(BeanConfig.class))
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {return;}
// Sort by previously determined @Order value, if applicable
configCandidates.sort((bd1, bd2) -> {int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {this.environment = new StandardEnvironment();
}
// 实例化 ConfigurationClassParser 时, 会 new 一个 ComponentScanAnnotationParser 对象,
// 用来解析 @ComponentScan 注解对应的 bean 信息
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
// 解析配置类, 变成 beanDefinition 退出 beanFactory 的 beanDefinitionMap 中
// 最终的解析过程是委托给了一个实例化的 ClassPathBeanDefinitionScanner 类
// 解析进去的配置类, 存储在 parser 的 configurationClasses 属性中
parser.parse(candidates);
parser.validate();
// 失去所有配置类的 bean 信息
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 通过 ConfigurationClass 加载更多的 BeanDefinition, 通过后面 parser.parse(candidates), 解析了 @bean 注解并保留在 ConfigurationClass 的 beanMethods
// 再通过 beanMethods, 生成 BeanDefinition 信息并注册到 beanDefinitionMap 中
// 将 @ImportResource 注解的资源引入 spring
// 将 @Import 注解的类, 生成 BeanDefinition 信息并注册到 beanDefinitionMap 中
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
// 如果进入到上面的代码中, 则示意原工程中有 @Configuration 注解的配置类
if (registry.getBeanDefinitionCount() > candidateNames.length) {String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {if (!oldCandidateNames.contains(candidateName)) {BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {// 相似递归, 若 @Configuration 注解的配置类管辖了另外的 @Configuration(不在 oldCandidateNames 汇合中), 再次循环
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext. ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();}
}
上面重点剖析一下步骤 4, 解析 @ComponentScan 的过程, 实际上调用的是 processConfigurationClass()办法, 次要是循环的调用 doProcessConfigurationClass(), 并且每次跳出循环, 都会将 configClass 注册到属性 configurationClasses 中
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {return;}
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {if (configClass.isImported()) {if (existingClass.isImported()) {existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one. this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// 递归的解决配置类 configClass 及其所继承的父类
// 从以后配置类 configClass 开始向上沿着类继承构造逐层执行 doProcessConfigurationClass(),
// 直到遇到的父类是由 Java 提供的类完结循环
SourceClass sourceClass = asSourceClass(configClass, filter);
do {sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
// 须要被解决的配置类 configClass 曾经被剖析解决,将它记录到已解决配置类记录
this.configurationClasses.put(configClass, configClass);
}
真正解决 @ComponentScan 的代码逻辑, 步骤如下:
- 收集所有被 @Component 注解并且在 @ComponentScan 指定的包下的 bean, 转换成 beanDefinition 注册到 spring 容器中
- 遍历步骤 1 中的 beanDefinition, 找出存在 @Configuration,@ComponentScan,@Component,@ImportResource 和 @Import 注解信息的 beanDefinition, 调用 parse()办法, 实际上, 再次调用次要是为了解析 @Bean,@ComponentScan,@ImportResource 和 @Import 注解, 目标也是为了注册这些注解代表的 beanDefinition
- 解决 @Import 注解
- 解决 @ImportResource 注解
- 解决 @Bean 注解
// TODO 解析的流程画个图
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {if (configClass.getMetadata().isAnnotated(Component.class.getName())) {// 递归解决外部类(外部类也有 @Component 注解, 须要注册到容器中)
processMemberClasses(configClass, sourceClass, filter);
}
// 解决 @PropertySource 注解
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");
}
}
// 解决 @ComponentScan 注解
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) {
// 此 configClass 存在 @ComponentScan 注解, 扫描获取 basePackages 的所有 bean 信息
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();
}
// 判断通过 @ComponentScan 扫描新退出的 bdCand, 是否存在 @Configuration,@ComponentScan,@Component,@ImportResource,@Import 注解,
// 若有, 则再次进入配置类的解析解决流程
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 解决 @Import 注解, 给 configClass 退出 ImportBeanDefinitionRegistrar, 后续会调用
// getImports(), 遍历并递归获取 sourceClass 的所有注解中蕴含 @import 注解的 value 值
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// 解决 @ImportResource 注解
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);
}
}
// 解决 @Bean 注解,获取注解的办法的相干元数据,比方办法名、所在类全名、返回类型、是否动态、是否不可笼罩等等信息
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;
}