spring如何标识全配置类和半配置类
在执行bean生命周期过程中, 内置的ConfigurationClassPostProcessor
会回调postProcessBeanDefinitionRegistry
执行方法org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
会进行判断是否是全配置类和半配置类
使用工具类org.springframework.context.annotation.ConfigurationClassUtils#checkConfigurationClassCandidate
进行标识
public static boolean checkConfigurationClassCandidate(
BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
/**
* 1、config==null 没有加Configuration
* 2、不等于null 加了Configuration
*/
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
//加了Configuration proxyBeanMethods =true 全配置类
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
else if (config != null || isConfigurationCandidate(metadata)) {
//没有加 Configuration 但是加了4个注解其中一个就是一个半配置类
/**
@Component.class @ComponentScan.class @Import.class @ImportResource
**/
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}
}
9-02-spring如何处理全配置类(会做一个增强
CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL
上面既然看到了一个地方标识, 再看看什么地方引用到这字段不就晓得标识之后是干嘛去了
发现在生命周期的org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanFactory
内会执行org.springframework.context.annotation.ConfigurationClassPostProcessor#enhanceConfigurationClasses
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
// If a @Configuration class gets proxied, always proxy the target class
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// Set enhanced subclass of the user-specified bean class
Class<?> configClass = beanDef.getBeanClass();
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (logger.isTraceEnabled()) {
logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
}
// 这个是增强后的class, 将原来的class做一个替换了, 此时此刻的bean其实还没有初始化的,只是被spring扫描出来, 以后创建bean的时候,使用这个增强的代理类
beanDef.setBeanClass(enhancedClass);
}
}
}
增强也有好处 比如@Bean方法, Spring能保证是单例的, 不然可能会遇到类似情况, 比如Spring事务失效什么的 具体可以看另外一篇文章 添加链接描述