直接上代码实例看效果
1、添加@Congfiguration的
@Configuration
@ComponentScan("com.lquan.scan.scan1")
public class Configration {
}
测试类
public class Test {
public static void main(String[] args) {
// 把spring所有的前提环境准备好
AnnotationConfigApplicationContext annotationConfigApplicationContext
= new AnnotationConfigApplicationContext(Configration.class);
Configration configration = annotationConfigApplicationContext.getBean(Configration.class);
}
}
运行结果:如图所示Spring这配置类生成bean的时候回家上CGLIB代理
2、不添加@Congfiguration的
@ComponentScan("com.lquan.scan.scan1")
public class Configration {
}
测试类
public class Test {
public static void main(String[] args) {
// 把spring所有的前提环境准备好
AnnotationConfigApplicationContext annotationConfigApplicationContext= new AnnotationConfigApplicationContext(Configration.class);
Configration configration =annotationConfigApplicationContext.getBean(Configration.class);
}
}
测试结果:没有配置类的时候,是不会走CGLIB代理的
3、源码分析
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
/**
* 判断是否是一个全注解类
* 扫描是全注解类?full和lite的关系
*/
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
if (!(beanDef instanceof AbstractBeanDefinition)) {
throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
}
else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
logger.warn("Cannot enhance @Configuration bean definition '" + beanName +
"' since its singleton instance has been created too early. The typical cause " +
"is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
"return type: Consider declaring such methods as 'static'.");
}
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
/**
* 配置类如果不加@Configuration,就只返回了
* 不再走下面的动态代理
*/
if (configBeanDefs.isEmpty()) {
// nothing to enhance -> return immediately
return;
}
/**
* cglib动态代理
*/
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);
try {
// Set enhanced subclass of the user-specified bean class
Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
if (configClass != null) {
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
}
beanDef.setBeanClass(enhancedClass);
}
}
}
catch (Throwable ex) {
throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
}
}
}
}
加了@Congfiguration配置文件的属性就会标识full类型,然后就configBeanDefs.isEmpty()判断时候是false,如果去掉了就会@Congfiguration是配置类的属性被标识为lite,然后configBeanDefs.isEmpty()判断为true,然后直接就返回了,不往下走了.
注释:ConfigurationClassEnhancer为动态代理生成类