这个工具类在Spring的BeanDefinition扫描加载阶段具有重要作用,我们来分析一下里面的几个方法,这里的方法都是静态方法,在这里做个笔记
isFullConfigurationCandidate
这个方法很简单,就是检测当前BeanDefinition对应的class类中是否有@Configuration注解

isFullConfigurationCandidate方法
isLiteConfigurationCandidate
判断当前BeanDefinition对应的class类上是否有@Component、@ComponentScan、@Import、@ImportResource、@Bean注解

isLiteConfigurationCandidate方法

candidateIndicators集合
isConfigurationCandidate
这方法是上面两个方法的或运算,判断是否是配置类

checkConfigurationClassCandidate
这个方法出现在ConfigurationClassPostProcessor的processConfigBeanDefinitions()中,用于判断当前的BeanDefinition是否是一个配置类的候选者(或一个在配置/组件类中声明的嵌套组件类),并对其进行相应的标记处理的,如果是则返回true,不是则返回false。

来具体分析一下这个方法:
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
//获取当前BeanDefinition的calass名字
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
AnnotationMetadata metadata;
//@Component、@Bean对应的是AnnotatedBeanDefinition
if (beanDef instanceof AnnotatedBeanDefinition &&
className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
// Can reuse the pre-parsed metadata from the given BeanDefinition...
//解析出来当前BeanDefinition对应的元数据(可以理解为对应的class信息)
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
//Spring内部的则是RootBeanDefinition,实现了AbstractBeanDefinition
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
// Check already loaded Class if present...
// since we possibly can't even load the class file for this Class.
//获取对应的class,然后创建一个元数据类
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
metadata = new StandardAnnotationMetadata(beanClass, true);
}
else {
try {
//metadataReaderFactory是一个CachingMetadataReaderFactory,继承了SimpleMetadataReaderFactory
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
metadata = metadataReader.getAnnotationMetadata();
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " + className, ex);
}
return false;
}
}
//判断类上是否有@Configuration注解,源代码在下面
if (isFullConfigurationCandidate(metadata)) {
//其实就是BeanDefinition中的一个map,记录一下标记
//这里key=org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass
//value=full
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
//判断类上是否有@Component、@ComponentScan、@Import、@ImportResource、@Bean注解
else if (isLiteConfigurationCandidate(metadata)) {
//这里key=org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass
//value=lite
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
//以上几个注解没有的话,则返回false;有的话返回true
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);
}
return true;
}