类图
负责解析处理所有@Configuration标签类,主要流程在ConfigurationClassParser中进行
postProcessBeanDefinitionRegistry
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
processConfigBeanDefinitions(registry);
}
processConfigBeanDefinitions
处理full和lite
先得到Spring内置的Bean定义和AnnotationConfigApplicationContext传进来的@Configuration
String[] candidateNames = registry.getBeanDefinitionNames(); // 目前都是spring内置的bean定义和 AnnotationConfigApplicationContext构造传进来的annotatedClasses
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { // 已经处理过了 full 、lite 已经标记打进去了
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { // 这里会处理full 、lite 如果2个都不是 返回false 有1个则返回true
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
这里最终得到的configCandidates,就是传进来的annotatedClasses
循环遍历解析configCandidates
// ConfigurationClassParser
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) { // 循环遍历configCandidates
BeanDefinition bd = holder.getBeanDefinition();
try {
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());
}
}
}
this.deferredImportSelectorHandler.process();
}
checkConfigurationClassCandidate
// 如果是@Configuration 会设置full
if (isFullConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
else if (isLiteConfigurationCandidate(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);
}
return true;
postProcessBeanFactory
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory); //对标记@Configuration注解的类 会cblig增强
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory)); // 添加ImportAwareBeanPostProcessor
}
isFullConfigurationClass
public static boolean isFullConfigurationClass(BeanDefinition beanDef) {
return CONFIGURATION_CLASS_FULL.equals(beanDef.getAttribute(CONFIGURATION_CLASS_ATTRIBUTE));
}
ConfigurationClassUtils
判断是否有Configuration注解
public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
return metadata.isAnnotated(Configuration.class.getName());
}
如果存在Configuration,则设置CONFIGURATION_CLASS_ATTRIBUTE属性为full
if (isFullConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
public void setAttribute(String name, @Nullable Object value) {
super.setAttribute(name, new BeanMetadataAttribute(name, value));
}
isLiteConfigurationCandidate
会判断是否存在下面4个注解中的1个,存在,则返回true
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
如果上面4个注解,都不存在,则判断是否存在Bean注解
return metadata.hasAnnotatedMethods(Bean.class.getName());
也就是存在上面5个中的1个,就返回true,否则返回false