spring @Configuration注解分析

1.@Configuration注解作用

@Configuration用于定义配置类,可替换xml配置文件
被注解的类内部包含有一个或多个被@Bean注解的方法,
这些方法将会被AnnotationConfigApplicationContextAnnotationConfigWebApplicationContext类进行扫描,
并用于构建bean定义,初始化Spring容器。

注意:@Configuration注解的配置类有如下要求:

@Configuration不可以是final类型;
@Configuration不可以是匿名类;
嵌套的configuration必须是静态类。

2. @Configuration注解使用

@Configuration
@ComponentScan(basePackages = "com.chr.test.configuration")
public class AppConfig {

    @Bean(name="userDao")
    public UserDao userDao(){
        System.out.println("注入UserDao");
        return new UserDao();
    }

    @Bean(name="orderDao")
    public OrderDao orderDao(){
        userDao();
        return new OrderDao();
    }
}
/**
 * @author chenhairong3
 * @description
 * @date 2020/12/16
 */
public class OrderDao {

    public  OrderDao(){
        System.out.println("OrderDao 无参构造函数被调用。");
    }
    public void insert() {
        System.out.println("OrderDao.insert()被调用。");
    }
}
/**
 * @author chenhairong3
 * @description
 * @date 2020/12/16
 */
public class UserDao {

    public UserDao(){
        System.out.println("UserDao 无参构造函数被调用。");
    }

    public void insert() {
        System.out.println("UserDao.insert()被调用。");
    }
}

测试类:

/**
 * @author chenhairong3
 * @description
 * @date 2020/12/16
 */
public class MainApplication {

    public static void main(String[] args) {
     
         AnnotationConfigApplicationContext configApplicationContext = new 
         AnnotationConfigApplicationContext(AppConfig.class);

         AppConfig appConfig = configApplicationContext.getBean(AppConfig.class);


         OrderDao orderDao = (OrderDao) configApplicationContext.getBean("orderDao");
         orderDao.insert();

         UserDao userDao = (UserDao) configApplicationContext.getBean("userDao");
         userDao.insert();
    
    }

}

输出:

注入UserDao
UserDao 无参构造函数被调用。
OrderDao 无参构造函数被调用。
OrderDao.insert()被调用。
UserDao.insert()被调用。

 

3.思考

     如果不使用@Configuration注解,bean会被实例化吗?如果实例化了,userDao会被实例化几次呢?

  

    直接上验证结果:

    

/**
 * @author chenhairong3
 * @description
 * @date 2020/12/16
 */
//@Configuration
@ComponentScan(basePackages = "com.chr.test.configuration")
public class AppConfig {

    @Bean(name="userDao")
    public UserDao userDao(){
        System.out.println("注入UserDao");
        return new UserDao();
    }

    @Bean(name="orderDao")
    public OrderDao orderDao(){
        userDao();
        return new OrderDao();
    }
}

    输出:

注入UserDao
UserDao 无参构造函数被调用。


注入UserDao
UserDao 无参构造函数被调用。
OrderDao 无参构造函数被调用。

OrderDao.insert()被调用。
UserDao.insert()被调用。

 

  从结果可以看出来,注释掉@Configuration注解,bean依然会被注入,但是userDao被注入了2次。

 

我们发现:

有@Configuration注解的时候,得到的appConfig对象是被cglib代理增加后的代理类对象

没有@Configuration注解的时候,得到的就是个普通的对象:

为什么会这样呢?就让我们带着疑问开始源码分析,解开@Configuration的神秘面纱。

4. 源码分析

  从表面来看,当我们不加@Configuration注解的时候,我们的UserDao会被实例化两次,这违背了我们spring默认单例的设计原则,当加上我们的@Configuration注解的时候,UserDao只被实例化了一次。那么其底层到底做了什么,让我们来深追一下spring源码吧。

 

先看下整个debug跟踪调用的代码链路。然后再一步步讲解每一步代码。

 

 

 

从上面debug的链路可以看到整体的调用链路是:

AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

从这个代码开始进入AnnotationConfigApplicationContext的构造函数:

 public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        this();
        this.register(annotatedClasses);
        this.refresh();
    }

构造函数中this方法里面会注入ConfigurationClassPostProcessor这个BeanFactoryPostProcessor扩展类。

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

 ConfigurationClassPostProcessor 实现了BeanDefinitionRegistryPostProcessor 这个接口。

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}

实现了这个接口的类,在容器bean实例化之前会调用 ConfigurationClassPostProcessor的如下2个方法

 1.postProcessBeanDefinitionRegistry()

 2.postProcessBeanFactory()

 

postProcessBeanDefinitionRegistry此方法会解析配置类(此例中的配置类AppConfig)中的元注解,比如@Configuration和@ComponetScan,然后解析元注解,如果注解是@Configuration注解,则设置属性:

beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");

非@Configuration注解,设置属性为:

beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "lite");

postProcessBeanFactory()方法中会判断如果属性值为full,则会基于cglib给配置类生成cglib代理类,在代理类中设置拦截器类

new ConfigurationClassEnhancer.BeanMethodInterceptor()。

在BeanMethodInterceptor的Interceptor方法中实现对方法的拦截。

Interceptor方法中重要的逻辑:

if (this.isCurrentlyInvokedFactoryMethod(beanMethod)) {
    if (ConfigurationClassEnhancer.logger.isWarnEnabled() && BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
        ConfigurationClassEnhancer.logger.warn(String.format("@Bean method %s.%s is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
    }
    //如果当前线程的方法和beanMethod方法相同时候,说明是第一次创建对象,则调用目标对象的方法来创建对象
    return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
} else {
   //如果当前线程的方法和beanMethod方法不相同时候,说明不是第一次创建对象,则直接从beanFactory中直接获取对象,保证单例。
    return this.resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}

 

具体详细代码分析如下:

我们先从AnnotationConfigApplicationContext入口类开始分析:

AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

进入对应的构造函数:

 public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        this();
        this.register(annotatedClasses);
        this.refresh();
    }

进入this方法:

public AnnotationConfigApplicationContext() {
    this.reader = new AnnotatedBeanDefinitionReader(this);
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

进入this.reader = new AnnotatedBeanDefinitionReader(this);

然后进入

AnnotationConfigUtils.registerAnnotationConfigProcessors()方法:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }

            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(4);
        RootBeanDefinition def;
        if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
            //在这里注入了ConfigurationClassPostProcessor这个类型的BeanDefinition
            def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
        }

        if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {
            def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
        }

        if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalRequiredAnnotationProcessor")) {
            def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalRequiredAnnotationProcessor"));
        }

        if (jsr250Present && !registry.containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")) {
            def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalCommonAnnotationProcessor"));
        }

        if (jpaPresent && !registry.containsBeanDefinition("org.springframework.context.annotation.internalPersistenceAnnotationProcessor")) {
            def = new RootBeanDefinition();

            try {
                def.setBeanClass(ClassUtils.forName("org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", AnnotationConfigUtils.class.getClassLoader()));
            } catch (ClassNotFoundException var6) {
                throw new IllegalStateException("Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", var6);
            }

            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalPersistenceAnnotationProcessor"));
        }

        if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerProcessor")) {
            def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerProcessor"));
        }

        if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerFactory")) {
            def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerFactory"));
        }

        return beanDefs;
    }

           
            def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); 上面最重要的代码,在这里注入了ConfigurationClassPostProcessor类型的BeanDefinition.用于解析@Configuration注解。

            题外话:

        上面还注入了另外几个比较重要的  PostProcessor。分别是

      AutowiredAnnotationBeanPostProcessor(用于解析@Autowired的注解等)
      RequiredAnnotationBeanPostProcessor(用于解析required的注解等)
       CommonAnnotationBeanPostProcessor(用于解析@PostConstruct 和 @PreDestroy等注解 )

       接下来开始进入ConfigurationClassPostProcessor源码进行分析:

     public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor

    上面已经说过ConfigurationClassPostProcessor继承自BeanDefinitionRegistryPostProcessor,而BeanDefinitionRegistryPostProcessor又继承自BeanFactoryPostProcessor。

    BeanDefinitionRegistryPostProcessor执行的时候会顺序调用如下2个方法。

    1.postProcessBeanDefinitionRegistry()

    2.postProcessBeanFactory()

    那么BeanFactoryPostProcessor什么时候被调用的呢?

    在容器刷新方法refresh中如下图中标红的部分就是BeanFactoryPostProcessor被调用的地方:

   

接下来进入PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors()方法:

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        Set<String> processedBeans = new HashSet();
        int var9;
        ArrayList currentRegistryProcessors;
        String[] postProcessorNames;
        if (beanFactory instanceof BeanDefinitionRegistry) {
            //这里beanFactory是DefaultListableBeanFactory,DefaultListableBeanFactory实现了BeanDefinitionRegistry接口。所以会进入if分支
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList();
            //初始的时候beanFactoryPostProcessors是空的,所以不会进入下面的while循环
            Iterator var6 = beanFactoryPostProcessors.iterator();

            while(var6.hasNext()) {
                BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                } else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            currentRegistryProcessors = new ArrayList();
            //获取BeanDefinitionRegistryPostProcessor这种类型的postProcessorNames ,正好ConfigurationClassPostProcessor满足,然后会被找到
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            String[] var18 = postProcessorNames;
            var9 = postProcessorNames.length;

            int var10;
            String ppName;
            for(var10 = 0; var10 < var9; ++var10) {
                ppName = var18[var10];
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            //这个方法里面最终会调postProcessor.postProcessBeanDefinitionRegistry(registry);,ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry这个方法此时会被调用
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            var18 = postProcessorNames;
            var9 = postProcessorNames.length;

            for(var10 = 0; var10 < var9; ++var10) {
                ppName = var18[var10];
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
            boolean reiterate = true;

            while(reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                String[] var21 = postProcessorNames;
                var10 = postProcessorNames.length;

                for(int var28 = 0; var28 < var10; ++var28) {
                    String ppName = var21[var28];
                    if (!processedBeans.contains(ppName)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                        reiterate = true;
                    }
                }

                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }
            //这里会调用BeanFacotyPostProcessor的postProcessor.postProcessBeanFactory(beanFactory);即postProcessBeanFactory(beanFactory)方法被调用的地方
            invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
            invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        } else {
            invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        }

        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList();
        List<String> orderedPostProcessorNames = new ArrayList();
        currentRegistryProcessors = new ArrayList();
        postProcessorNames = postProcessorNames;
        int var22 = postProcessorNames.length;

        String ppName;
        for(var9 = 0; var9 < var22; ++var9) {
            ppName = postProcessorNames[var9];
            if (!processedBeans.contains(ppName)) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                } else {
                    currentRegistryProcessors.add(ppName);
                }
            }
        }

        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors((Collection)priorityOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList();
        Iterator var23 = orderedPostProcessorNames.iterator();

        while(var23.hasNext()) {
            String postProcessorName = (String)var23.next();
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }

        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
        Iterator var26 = currentRegistryProcessors.iterator();

        while(var26.hasNext()) {
            ppName = (String)var26.next();
            nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }

        invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        beanFactory.clearMetadataCache();
    }

从上面可以可以,会顺序调用ConfigurationClassPostProcessor的如下2个方法:

1.postProcessBeanDefinitionRegistry() 此方法用于解析Configuration注解,如果

配置类上有@Configuration注解,则设置属性 beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");

否则则设置属性:

beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "lite");

2.postProcessBeanFactory()

    此方法会判断上面的属性值是否为“full”,如果是则生成配置类的增加类,并设置方法拦截,在拦截器方法内,实现单例的控制。

 

postProcessBeanDefinitionRegistry方法源码:

 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        int registryId = System.identityHashCode(registry);
        if (this.registriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
        } else if (this.factoriesPostProcessed.contains(registryId)) {
            throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
        } else {
            this.registriesPostProcessed.add(registryId);
            //在这里进行解析
            this.processConfigBeanDefinitions(registry);
        }
    }

//在这里进行解析
            this.processConfigBeanDefinitions(registry);

进入此方法:

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        List<BeanDefinitionHolder> configCandidates = new ArrayList();
        String[] candidateNames = registry.getBeanDefinitionNames();
        String[] var4 = candidateNames;
        int var5 = candidateNames.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            String beanName = var4[var6];
            BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            if (!ConfigurationClassUtils.isFullConfigurationClass(beanDef) && !ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
                    configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
                }
            } else if (this.logger.isDebugEnabled()) {
                this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
            }
        }

        if (!configCandidates.isEmpty()) {
            configCandidates.sort((bd1, bd2) -> {
                int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
                int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
                return Integer.compare(i1, i2);
            });
            SingletonBeanRegistry sbr = null;
            if (registry instanceof SingletonBeanRegistry) {
                sbr = (SingletonBeanRegistry)registry;
                if (!this.localBeanNameGeneratorSet) {
                    BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
                    if (generator != null) {
                        this.componentScanBeanNameGenerator = generator;
                        this.importBeanNameGenerator = generator;
                    }
                }
            }

            if (this.environment == null) {
                this.environment = new StandardEnvironment();
            }

            ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
            Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
            HashSet alreadyParsed = new HashSet(configCandidates.size());

            do {
                //在这里进行解析
                parser.parse(candidates);
                parser.validate();
                Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
                configClasses.removeAll(alreadyParsed);
                if (this.reader == null) {
                    this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());
                }

                this.reader.loadBeanDefinitions(configClasses);
                alreadyParsed.addAll(configClasses);
                candidates.clear();
                if (registry.getBeanDefinitionCount() > candidateNames.length) {
                    String[] newCandidateNames = registry.getBeanDefinitionNames();
                    Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));
                    Set<String> alreadyParsedClasses = new HashSet();
                    Iterator var12 = alreadyParsed.iterator();

                    while(var12.hasNext()) {
                        ConfigurationClass configurationClass = (ConfigurationClass)var12.next();
                        alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
                    }

                    String[] var23 = newCandidateNames;
                    int var24 = newCandidateNames.length;

                    for(int var14 = 0; var14 < var24; ++var14) {
                        String candidateName = var23[var14];
                        if (!oldCandidateNames.contains(candidateName)) {
                            BeanDefinition bd = registry.getBeanDefinition(candidateName);
                            if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                                candidates.add(new BeanDefinitionHolder(bd, candidateName));
                            }
                        }
                    }

                    candidateNames = newCandidateNames;
                }
            } while(!candidates.isEmpty());

            if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
                sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
            }

            if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
                ((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache();
            }

        }
    }

进入

ConfigurationClassParser的parse方法:

最终会调到如下方法:

进入

doProcessConfigurationClass方法:

public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
        String className = beanDef.getBeanClassName();
        if (className != null && beanDef.getFactoryMethodName() == null) {
            Object metadata;
            if (beanDef instanceof AnnotatedBeanDefinition && className.equals(((AnnotatedBeanDefinition)beanDef).getMetadata().getClassName())) {
                metadata = ((AnnotatedBeanDefinition)beanDef).getMetadata();
            } else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)beanDef).hasBeanClass()) {
                Class<?> beanClass = ((AbstractBeanDefinition)beanDef).getBeanClass();
                metadata = new StandardAnnotationMetadata(beanClass, true);
            } else {
                try {
                    MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
                    metadata = metadataReader.getAnnotationMetadata();
                } catch (IOException var5) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Could not find class file for introspecting configuration annotations: " + className, var5);
                    }

                    return false;
                }
            }

            if (isFullConfigurationCandidate((AnnotationMetadata)metadata)) {
                //在这里放入属性值
                beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
            } else {
                if (!isLiteConfigurationCandidate((AnnotationMetadata)metadata)) {
                    return false;
                }

                beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "lite");
            }

            Integer order = getOrder((AnnotationMetadata)metadata);
            if (order != null) {
                beanDef.setAttribute(ORDER_ATTRIBUTE, order);
            }

            return true;
        } else {
            return false;
        }
    }

isFullConfigurationCandidate方法源码: 

public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
    return metadata.isAnnotated(Configuration.class.getName());
}

可以看到会判断如果有Configuration注解,则设置属性:beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");

至此postProcessBeanDefinitionRegistry方法源码分析结束。主要逻辑就是获取配置类上的元注解,找到是否有@Configuration注解,有的话则设置beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");

 

 

接下来重点分析postProcessBeanFactory方法:

进入enhanceConfigurationClasses方法,在这里会生成代理类,实现方法增强:

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
        Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap();
        String[] var3 = beanFactory.getBeanDefinitionNames();
        int var4 = var3.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String beanName = var3[var5];
            BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
            if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
                //在这里会判断属性,如果属性值为full
                if (!(beanDef instanceof AbstractBeanDefinition)) {
                    throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" + beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
                }

                if (this.logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
                    this.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'.");
                }
                //如果属性值为full 则把beanDefinition加入configBeanDefs map中
                configBeanDefs.put(beanName, (AbstractBeanDefinition)beanDef);
            }
        }

        if (!configBeanDefs.isEmpty()) {
            //因为上面加入过值,所以这里configBeanDefs肯定不会为空
            ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
            Iterator var11 = configBeanDefs.entrySet().iterator();

            while(var11.hasNext()) {
                Entry<String, AbstractBeanDefinition> entry = (Entry)var11.next();
                AbstractBeanDefinition beanDef = (AbstractBeanDefinition)entry.getValue();
                beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);

                try {
                    Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
                    if (configClass != null) {
                        //使用cglib动态代理生成代理类
                        Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
                        if (configClass != enhancedClass) {
                            if (this.logger.isDebugEnabled()) {
                                this.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 var9) {
                    throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), var9);
                }
            }

        }
    }

 进入

 

从源码可以看出,通过cglib动态代理生成了当前配置的的子类(enhancer.setSuperclass(configSuperClass);),然后设置了回调拦截器,

CALLBACKS = new Callback[]{new ConfigurationClassEnhancer.BeanMethodInterceptor(), new ConfigurationClassEnhancer.BeanFactoryAwareMethodInterceptor(), NoOp.INSTANCE};
然后进入new ConfigurationClassEnhancer.BeanMethodInterceptor()中的intercept方法
 @Nullable
        public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs, MethodProxy cglibMethodProxy) throws Throwable {
            ConfigurableBeanFactory beanFactory = this.getBeanFactory(enhancedConfigInstance);
            String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
            Scope scope = (Scope)AnnotatedElementUtils.findMergedAnnotation(beanMethod, Scope.class);
            if (scope != null && scope.proxyMode() != ScopedProxyMode.NO) {
                String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
                if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
                    beanName = scopedBeanName;
                }
            }

            if (this.factoryContainsBean(beanFactory, "&" + beanName) && this.factoryContainsBean(beanFactory, beanName)) {
                Object factoryBean = beanFactory.getBean("&" + beanName);
                if (!(factoryBean instanceof ScopedProxyFactoryBean)) {
                    return this.enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
                }
            }

            if (this.isCurrentlyInvokedFactoryMethod(beanMethod)) {
                //在这里判断如果当前线程调用的方法和目标方法一样,则表示是第一次创建,则调用代理类的父类(即目标类)方法,注入实例
                if (ConfigurationClassEnhancer.logger.isWarnEnabled() && BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
                    ConfigurationClassEnhancer.logger.warn(String.format("@Bean method %s.%s is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
                }

                return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
            } else {
                // 在这里判断如果当前线程调用的方法和目标方法不一样,则表示以前创建过,则直接从beanFactory工厂通过beanName 获取实例
                return this.resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
            }
        }

实现单例控制的重点代码:

if (this.isCurrentlyInvokedFactoryMethod(beanMethod)) {
                //在这里判断如果当前线程调用的方法和目标方法一样,则表示是第一次创建,则调用代理类的父类(即目标类)方法,注入实例
                if (ConfigurationClassEnhancer.logger.isWarnEnabled() && BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
                    ConfigurationClassEnhancer.logger.warn(String.format("@Bean method %s.%s is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
                }

                return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
            } else {
                // 在这里判断如果当前线程调用的方法和目标方法不一样,则表示以前创建过,则直接从beanFactory工厂通过beanName 获取实例
                return this.resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
            }

比如测试代码中:

@Bean(name="orderDao")
public OrderDao orderDao(){
    userDao();
    return new OrderDao();
}

this.isCurrentlyInvokedFactoryMethod(beanMethod)这个方法中,执行到 userDao()这个代码的时候,beanMethod即userDao,而当前线程调用到的方法确实orderDao,方法不同,所以会走到return this.resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);从beanFactory中获取bean实例,而不是重新创建,从而实现单例控制。

可以看debug示例:

 

接下来看resolveBeanference()方法:

 private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs, ConfigurableBeanFactory beanFactory, String beanName) {
            boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);

            Object var20;
            try {
                if (alreadyInCreation) {
                    beanFactory.setCurrentlyInCreation(beanName, false);
                }

                boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
                if (useArgs && beanFactory.isSingleton(beanName)) {
                    Object[] var7 = beanMethodArgs;
                    int var8 = beanMethodArgs.length;

                    for(int var9 = 0; var9 < var8; ++var9) {
                        Object arg = var7[var9];
                        if (arg == null) {
                            useArgs = false;
                            break;
                        }
                    }
                }

                 //重点,从beanFactory中获取bean实例
                Object beanInstance = useArgs ? beanFactory.getBean(beanName, beanMethodArgs) : beanFactory.getBean(beanName);
                if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
                    if (!beanInstance.equals((Object)null)) {
                        String msg = String.format("@Bean method %s.%s called as bean reference for type [%s] but overridden by non-compatible bean instance of type [%s].", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(), beanMethod.getReturnType().getName(), beanInstance.getClass().getName());

                        try {
                            BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
                            msg = msg + " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription();
                        } catch (NoSuchBeanDefinitionException var14) {
                        }

                        throw new IllegalStateException(msg);
                    }

                    if (ConfigurationClassEnhancer.logger.isDebugEnabled()) {
                        ConfigurationClassEnhancer.logger.debug(String.format("@Bean method %s.%s called as bean reference for type [%s] returned null bean; resolving to null value.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(), beanMethod.getReturnType().getName()));
                    }

                    beanInstance = null;
                }

                Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
                if (currentlyInvoked != null) {
                    String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked);
                    beanFactory.registerDependentBean(beanName, outerBeanName);
                }

                var20 = beanInstance;
            } finally {
                if (alreadyInCreation) {
                    beanFactory.setCurrentlyInCreation(beanName, true);
                }

            }

            return var20;
        }

 

至此源码分析到此结束。

流程总结:

在refresh方法之前注入ConfigurationClassPostProcessor这个BeanFacotryPostProcessor,然后再refresh方法

this.invokeBeanFactoryPostProcessors(beanFactory);中,ConfigurationClassPostProcessor被调用,然后依次执行类中的如下2个方法:
postProcessBeanDefinitionRegistry() 此方法完成对配置类的注解进行解析,如果有@Configuration注解,则设置属性为:beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
postProcessBeanFactory()方法。在这个方法会判断上面的属性是有为full,如果是,则给配置类生成cglib代理类,给代理类上设置MethodInterceptor拦截器,在interceptor()方法对目标方法增强。

如果拦截方法和当前线程调用方法一样,则调用目标类的方法生成bean实例,否则从beanFactory根据beanName获取bean实例,实现单例的控制。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值