@Configuration 注解使用及源码解析

本文为博主原创,转载请注明出处: 

  @Configuration 注解对我们来说并不陌生,以javaConfig的方式定义spring IOC容器的配置类使用的就是这个@Configuration.

  spring boot 社区推荐使用基于JavaConfig 的配置方式来定义Bean,其可以认为是一个spring IOC 容器的配置类。

  指示一个类声明一个或多个@Bean方法,并且可以由Spring容器处理,以便在运行时为这些bean生成BeanDefinition和服务请求

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class TestConfiguration {
    /**
     * 初始化spring -restTemplate
     * @return restTemplate
     */
    @Bean
    public RestTemplate getRestTemplate(){
        System.out.println("获取bean ing");
        return new RestTemplate();
    }
    public TestConfiguration() {
        System.out.println("TestConfiguration容器启动初始化。。。");
    }
}

  

  @Configuration 注解的工作过程与 ClassXmlPathApplicationContext  的工作过程相同,@Configuration 是通过注解的方式将 bean 注入到spring IOC容器。

ClassXmlPathApplicationContext 是通过xml配置文件,在项目启动加载xml 配置文件时,将其中的bean 标签解析为bena 并注入到 IOC 容器中。

  通过 @Configuration 注解的配置类会通过 AnnotationConfigApplicationContext  类进行扫描,并构建扫描 bean ,并注册到spring IoC容器中。

可以通过以下测试方法,看到上面代码中的bean 初始化并调用相关过程的打印:

import com.example.test.config.TestConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.web.client.RestTemplate;

public class ConfigurationBeanTest {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
        RestTemplate restTemplate = (RestTemplate) context.getBean("getRestTemplate");
        String url = "https://www.baidu.com/?tn=62095104_19_oem_dg";
        String result = restTemplate.getForObject(url,String.class);
        System.out.println(result);
    }
}

上面test运行并进行正常的 http 请求,可以打印出相关的控制台日志如下:

 

 可以查看下 AnnotationConfigApplicationContext  类的相关实现,该类的继承结构通过idea 查看如下:

 

 

 其中主要涉及到的类和接口如下:

  1. GenericApplicationContext——通用应用上下文,内部持有一个DefaultListableBeanFactory实例,这个类实现了BeanDefinitionRegistry接口,可以在它身上使用任意的bean definition读取器。典型的使用案例是:通过BeanFactoryRegistry接口注册bean definitions,然后调用refresh()方法来初始化那些带有应用上下文语义(org.springframework.context.ApplicationContextAware)的bean,自动探测org.springframework.beans.factory.config.BeanFactoryPostProcessor等。关于这两个接口,在介绍bean的生命周期时进行详细讲解。
  2. BeanDefinitionRegistry——用于持有像RootBeanDefinition和 ChildBeanDefinition实例的bean definitions的注册表接口。DefaultListableBeanFactory实现了这个接口,因此可以通过相应的方法向beanFactory里面注册bean。GenericApplicationContext内置一个DefaultListableBeanFactory实例,它对这个接口的实现实际上是通过调用这个实例的相应方法实现的。
  3. AbstractApplicationContext——ApplicationContext接口的抽象实现,没有强制规定配置的存储类型,仅仅实现了通用的上下文功能。这个实现用到了模板方法设计模式,需要具体的子类来实现其抽象方法。自动通过registerBeanPostProcessors()方法注册BeanFactoryPostProcessorBeanPostProcessorApplicationListener的实例用来探测bean factory里的特殊bean——对比1分析
  4. AnnotationConfigRegistry——注解配置注册表。用于注解配置应用上下文的通用接口,拥有一个注册配置类和扫描配置类的方法。

 AnnotationConfigApplicationContext  类的源码如下:

  

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.context.annotation;

import java.util.Arrays;
import java.util.function.Supplier;
import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.metrics.StartupStep;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
    private final AnnotatedBeanDefinitionReader reader;
    private final ClassPathBeanDefinitionScanner scanner;

  // 无参数的构造器,在application 启动的时候初始化一个读取器与扫描器
public AnnotationConfigApplicationContext() { StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create"); this.reader = new AnnotatedBeanDefinitionReader(this); createAnnotatedBeanDefReader.end(); this.scanner = new ClassPathBeanDefinitionScanner(this); }   // 构造一个 bean 工厂的有参构造,并包含了读取器和扫描器 public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) { super(beanFactory); this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }   
  
  // 手动指定注解类
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { this(); this.register(componentClasses); this.refresh(); }   

   // 通过指定的包名进行自动的扫描并刷新
public AnnotationConfigApplicationContext(String... basePackages) { this(); this.scan(basePackages); this.refresh(); } public void setEnvironment(ConfigurableEnvironment environment) { super.setEnvironment(environment); this.reader.setEnvironment(environment); this.scanner.setEnvironment(environment); } public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) { this.reader.setBeanNameGenerator(beanNameGenerator); this.scanner.setBeanNameGenerator(beanNameGenerator); this.getBeanFactory().registerSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator", beanNameGenerator); } public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) { this.reader.setScopeMetadataResolver(scopeMetadataResolver); this.scanner.setScopeMetadataResolver(scopeMetadataResolver); } public void register(Class<?>... componentClasses) { Assert.notEmpty(componentClasses, "At least one component class must be specified"); StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register").tag("classes", () -> { return Arrays.toString(componentClasses); }); this.reader.register(componentClasses); registerComponentClass.end(); } public void scan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); StartupStep scanPackages = this.getApplicationStartup().start("spring.context.base-packages.scan").tag("packages", () -> { return Arrays.toString(basePackages); }); this.scanner.scan(basePackages); scanPackages.end(); } public <T> void registerBean(@Nullable String beanName, Class<T> beanClass, @Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) { this.reader.registerBean(beanClass, beanName, supplier, customizers); } }

 

   Spring将被@Configuration注解的配置类定义为full configuration, 而将没有被@Configuration注解的配置类定义为lite configuration。full configuration能重定向从跨方法的引用,

从而保证上述代码中的b bean是一个单例.

  调用 ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry 会将 AppConfig 的配置 类属性标注为full。其调用的流程图如下:

 

 其判断是否full的代码如下:

   Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
            if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
                beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
            } else {
                if (config == null && !isConfigurationCandidate(metadata)) {
                    return false;
                }

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

 

跟踪 AnnotationConfigApplicationContext.refresh() 方法:

  

    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
        // Prepare this context for refreshing.
this.prepareRefresh();
        // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory
= this.obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
this.prepareBeanFactory(beanFactory); try {
          // Allows post-processing of the bean factory in context subclasses.
          //供上下文(Context)子类继承,允许在这里后置处理bean factory
this.postProcessBeanFactory(beanFactory); StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
          // Invoke factory processors registered as beans in the context.
          //按顺序调用BeanFactoryPostProcessor,这里的按顺序仅实现了PriorityOrdered和Ordered的语意,未实现@Order注解的语意
          //通过调用ConfigurationConfigPostProcessor#postProcessBeanDefinitionRegistry
          //解析@Configuration配置类,将自定义的BeanFactoryPostProcessor、BeanPostProcessor注册到beanDefinitionMap
          //接着实例化所有(包括开天辟地)的BeanFactoryPostProcessor,然后再调用BeanFactoryPostProcessor#postProcessBeanFactory
this.invokeBeanFactoryPostProcessors(beanFactory);
          // Register bean processors that intercept bean creation.
          //按顺序将BeanPostProcessor实例化成bean并注册到beanFactory的beanPostProcessors,
          //这里的按顺序仅实现了PriorityOrdered和Ordered的语意,未实现@Order注解的语意
          //因为BeanPostProcessor要在普通bean初始化()前后被调用,所以需要提前完成实例化并注册到beanFactory的beanPostProcessors
this.registerBeanPostProcessors(beanFactory); beanPostProcess.end();
          // Initialize message source for this context.
          //注册国际化相关的Bean
this.initMessageSource();
          // Initialize event multicaster for this context.
          //为上下文注册应用事件广播器(用于ApplicationEvent的广播),如果有自定义则使用自定义的,如果没有则内部实例化一个
this.initApplicationEventMulticaster();
          // Initialize other special beans in specific context subclasses.
this.onRefresh();
          // Check for listener beans and register them.
          //注册所有(静态、动态)的listener,并广播earlyApplicationEvents
this.registerListeners();
          // Instantiate all remaining (non-lazy-init) singletons.
          //实例化用户自定义的普通单例Bean(非开天辟地的、非后置处理器)
this.finishBeanFactoryInitialization(beanFactory);
          // Last step: publish corresponding event.
this.finishRefresh(); } catch (BeansException var10) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10); } this.destroyBeans(); this.cancelRefresh(var10); throw var10; } finally { this.resetCommonCaches(); contextRefresh.end(); } } }

跟踪invokeBeanFactoryPostProcessors(beanFactory)

  protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
     // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
     // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!IN_NATIVE_IMAGE && beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }

跟踪invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

 

public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        Set<String> processedBeans = new HashSet<>();

        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            //此处调用ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry,
            //解析配置类,为配置中的bean定义生成对应beanDefinition,并注入到registry的beanDefinitionMap
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                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();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    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();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            //调用ConfigurationClassPostProcessor#postProcessBeanFactory增强配置类(通过cglib生成增强类,load到jvm内存,
            //设置beanDefinition的beanClass为增强类)
            //为什么要增强配置类?主要是为了让@Bean生成的bean是单例,
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        beanFactory.clearMetadataCache();
    }


跟踪invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
private static void invokeBeanFactoryPostProcessors(
      Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

   for (BeanFactoryPostProcessor postProcessor : postProcessors) {
      postProcessor.postProcessBeanFactory(beanFactory);
   }
}

跟踪ConfigurationClassPostProcessor#postProcessBeanFactory

@Override
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);
   }
   //为@Configuration注解的类生成增强类(如果有必要),并替换bd中的beanClass属性,
   enhanceConfigurationClasses(beanFactory);
   beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

到了这一步谜底几乎已经揭晓了,@Configuration class是通过增强来实现它的语义的。通过增强把跨方法的引用调用重定向到Spring生命周期管理.我们近一步探索下这个enhanceConfigurationClasses方法

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
   Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
   for (String beanName : beanFactory.getBeanDefinitionNames()) {
      BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
      Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
      MethodMetadata methodMetadata = null;
      if (beanDef instanceof AnnotatedBeanDefinition) {
         methodMetadata = ((AnnotatedBeanDefinition) beanDef).getFactoryMethodMetadata();
      }
      if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
         // Configuration class (full or lite) or a configuration-derived @Bean method
         // -> resolve bean class at this point...
         AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef;
         if (!abd.hasBeanClass()) {
            try {
               abd.resolveBeanClass(this.beanClassLoader);
            }
            catch (Throwable ex) {
               throw new IllegalStateException(
                     "Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
            }
         }
      }
      //在ConfigurationClassUtils.checkConfigurationClassCandidate方法中会标记Configuration is full or lite
      if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
         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.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
            logger.info("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);
      }
   }
   if (configBeanDefs.isEmpty()) {
      // nothing to enhance -> return immediately
      return;
   }

   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();
      //为@Configuration注解的类生成增强类
      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()));
         }
         beanDef.setBeanClass(enhancedClass);
      }
   }
}

看到有那么一句话 

Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);

  很明显了,使用cglib技术为config class生成一个enhancedClass,再通过beanDef.setBeanClass(enhancedClass);修改beanDefinition的BeanClass属性,在bean实例化阶段,会利用反射技术将beanClass属性对应的类实例化出来,所以最终实例化出来的@Configuration bean是一个代理类的实例。这里稍微提一下为什么要使用cglib,而不是jdk动态代理,主要是因为jdk动态代理是基于接口的,而这里AppConfig并没有实现任何接口,所以必须用cglib技术。

总结

被@Configuration 注解的类,是 full configuration class,该类会被增强(通过cglib),从而实现跨方法引用调用被重定向到Spring 生命周期管理,最终保证@Bean method生成的bean是一个单例。

 

 

参考博客:热心市民小陈  https://www.cnblogs.com/think-in-java/p/11876997.html

 

posted @ 2020-11-29 22:49  香吧香  阅读(2451)  评论(0编辑  收藏  举报