spring中只有标注`@Configurtion`的类才是配置类吗?答案:**不是的**


传送:

Spring大观园,我有过的困惑或许你也有!

导读

spring内部对配置类分为两种,区分的办法是:
解析后,在beanDef中添加属性"configurationClass",其值分两种,要么是"full" ,要么是"lite";

1.  beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
2.  beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);

替换常量后是这样

1.  beanDef.setAttribute("configurationClass"), "full");
2.  beanDef.setAttribute("configurationClass"), "lite");

有何区别

  1. full类的是带有@Configuration注解的配置类
  2. lite类的是
    2.1 类上带有注解@Component@ComponentScan@Import@Component@ImportResource
    2.2 类中的方法带有注解@Bean

避免重复解析

因为解析后,会在beanDef中setAttribute("configurationClass"), "full"/"lite");
所以,如果beanDef.getAttribute("configurationClass")不是null 就是被解析过了

if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
                }
            }

源码视角

注解方式的配置类 的解析操作从
ConfigurationClassPostProcessor#processConfigBeanDefinitions方法中查看,
其中有个判断配置类的方法有点特别
ConfigurationClassUtils.checkConfigurationClassCandidate

...
        Map config = metadata.getAnnotationAttributes(Configuration.class.getName());
        if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
           //如果有有注解@Configuration,且其元数据中有"proxyBeanMethods",则为 full
            beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
        }
        else if (config != null || isConfigurationCandidate(metadata)) {
            // lite 自己跟踪其源码一看便知
            beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
        }
        else {
            return false;
        }
...
了解配置类

如果是配置类,spring会对其进行解析,导入、扫描BeanDefinition,配置类解析从两个视角来:

  • 脑图全晰视角:配置类解析流程
  • 源码注释版的链接稍后敬上。
元数据中"proxyBeanMethods"的作用

你可能感兴趣的:(spring中只有标注`@Configurtion`的类才是配置类吗?答案:**不是的**)