spring是如何判断一个类是否是配置类
配置类是如何注册成bd的
AnnotatedGenericBeanDefinition 配置类bd
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 1. 创建BeanFactory
// 2. 生成AnnotatedBeanDefinitionReader
// 3. 生成ClassPathBeanDefinitionScanner
this();
// 利用reader把componentClasses注册为一个BeanDefinition
register(componentClasses);
register(componentClasses); 把一个配置类解析成bd并注册到bean容器中
如何判断一个类是否是配置类
// 注意,并不是没有Configuration注解当前BeanDefinition就不是一个配置类
// 注意isConfigurationCandidate方法,会检查是否存在@Component, @ComponentScan,@Import,@ImportResource,@Bean注解
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
isConfigurationCandidate 的方法如下:
private static final Set<String> candidateIndicators = new HashSet<>(8);
static {
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
}
public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
// Do not consider an interface or an annotation...
if (metadata.isInterface()) {
return false;
}
// Any of the typical annotations found?
// candidateIndicators
for (String indicator : candidateIndicators) {
if (metadata.isAnnotated(indicator)) {
return true;
}
}
// Finally, let's look for @Bean methods...
try {
return metadata.hasAnnotatedMethods(Bean.class.getName());
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
}
return false;
}
}
通过上述方法判断一个类是否是配置类
找到配置类开始解析
public void parse(Set<BeanDefinitionHolder> configCandidates) {
// 遍历多个配置类的BeanDefinition
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
// 处理有注解的BeanDefinition
if (bd instanceof AnnotatedBeanDefinition) {
// 处理注解的信息
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
this.deferredImportSelectorHandler.process();
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
// ConfigurationClass表示配置类信息,包括配置上的注解信息,和beanName,以及还有一个resource属性,表示配置类的类路径
processConfigurationClass(new ConfigurationClass(metadata