enableautoconfiguration_深入理解EnableAutoConfiguration原理

510873930132a37386db5fedddabbb07.png


文章来源:https://my.oschina.net/lt0314/blog/4335365

源码分析@EnableAutoConfiguration在SpringBoot中的加载和实例化过程

万里长征第一步,我们先理解下什么是EnableAutoConfiguration?

什么是EnableAutoConfiguration注解?

在哪?

org.springframework.boot.autoconfigure.EnableAutoConfiguration

EnableAutoConfiguration概述

我们先来看下源码

package org.springframework.boot.autoconfigure;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;import org.springframework.context.annotation.Conditional;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.core.io.support.SpringFactoriesLoader;/** * Enable auto-configuration of the Spring Application Context, attempting to guess and * configure beans that you are likely to need. Auto-configuration classes are usually * applied based on your classpath and what beans you have defined. For example, If you * have {@code tomcat-embedded.jar} on your classpath you are likely to want a * {@link TomcatEmbeddedServletContainerFactory} (unless you have defined your own * {@link EmbeddedServletContainerFactory} bean). *  * When using {@link SpringBootApplication}, the auto-configuration of the context is * automatically enabled and adding this annotation has therefore no additional effect. *  * Auto-configuration tries to be as intelligent as possible and will back-away as you * define more of your own configuration. You can always manually {@link #exclude()} any * configuration that you never want to apply (use {@link #excludeName()} if you don't * have access to them). You can also exclude them via the * {@code spring.autoconfigure.exclude} property. Auto-configuration is always applied * after user-defined beans have been registered. *  * The package of the class that is annotated with {@code @EnableAutoConfiguration}, * usually via {@code @SpringBootApplication}, has specific significance and is often used * as a 'default'. For example, it will be used when scanning for {@code @Entity} classes. * It is generally recommended that you place {@code @EnableAutoConfiguration} (if you're * not using {@code @SpringBootApplication}) in a root package so that all sub-packages * and classes can be searched. *  * Auto-configuration classes are regular Spring {@link Configuration} beans. They are * located using the {@link SpringFactoriesLoader} mechanism (keyed against this class). * Generally auto-configuration beans are {@link Conditional @Conditional} beans (most * often using {@link ConditionalOnClass @ConditionalOnClass} and * {@link ConditionalOnMissingBean @ConditionalOnMissingBean} annotations). */@SuppressWarnings("deprecation")@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {  String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";  /**   * Exclude specific auto-configuration classes such that they will never be applied.   * @return the classes to exclude   */  Class>[] exclude() default {};  /**   * Exclude specific auto-configuration class names such that they will never be   * applied.   * @return the class names to exclude   * @since 1.3.0   */  String[] excludeName() default {};}
类图

21f8550da6ac1c36f8b2174c9319202e.png

注意“@Import(EnableAutoConfigurationImportSelector.class)” 部分。后边源码分析中会使用到。

说明

EnableAutoConfiguration注解的功能大概如下。

  • 开启Spring应该上下文的自动配置,尽可能去加载需要的配置Beans。自动配置类,一般是根据你的classpath路径来应用的。

  • 当你使用了SpringBootApplication注解,在context中自动加载配置就已经开启,不需要其他操作。

  • 可以通过exclude()传入Class类型;excludeName() 传入名称来排除其他类型的加载。自动加载的配置始终是在普通用户定义的Bean加载之后执行。

  • 默认EnableAutoConfiguration扫描的是当前启用注解的Class对象的目录作为root目录。所以这个目录下的所有子目录都会被扫描。

  • 自动装载的配置类,也是常规的SpringBean(被@Configuration修饰,@Configuration则被@Component修饰(如果你写的@Configuration在启动类的包名下,开启注解扫描的情况下,也是会把@Configuration注册为Bean对象。))。当然也可以通过SpringFactoriesLoader的机制来定位到对应的org.springframework.boot.autoconfigure.EnableAutoConfiguration类(不在同用户扫描包目录中)。

  • 一般配合Conditional、ConditionalOnClass、ConditionalOnMissingBean一起使用。

测试项目

│  pom.xml└─src    └─main        ├─java        │  └─com        │      └─baigt        │          ├─autoconfig        │          │      BaigtAutoConfig.java        │          │              │          └─sb        │                  SBStarter.java        │                          └─resources            └─META-INF                    spring.factories
  • pom

<?xml version="1.0" encoding="UTF-8"?>         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    4.0.0    org.baigt    SpringBootCodeAnalyze    1.0-SNAPSHOT            org.springframework.boot        spring-boot-starter-parent        1.5.14.RELEASE                            org.springframework.boot            spring-boot-starter                                                    org.springframework.boot                spring-boot-maven-plugin                        
  • BaigtAutoConfig

注意和启动类不在一个目录中

package com.baigt.autoconfig;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * 测试Autoconfig */@Configurationpublic class BaigtAutoConfig {    @Bean    public String env(){        return new String("Baigt Test");    }}
  • SBStarter

注意和config不在一个目录 中

package com.baigt.sb;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;/** * 测试@EnableAutoConfig加载的流程(加载自定义的配置类,不在同一个目录中) */@SpringBootApplicationpublic class SBStarter{    public static void main(String[] args) {        SpringApplication sb=new SpringApplication(SBStarter.class);        ConfigurableApplicationContext run = sb.run(args);        System.out.println(run.getBean("baigt",String.class));    }}
  • spring.factories

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.baigt.autoconfig.BaigtAutoConfig

正题(源码)

我们只分析和EnableAutoConfiguration相关的源码。

new SpringApplication

初始化环境(是否是web),设置ApplicationContextInitializer、ApplicationListener,设置启动类的class到mainApplicationClass上。我们的例子中不是web环境。

//初始化入口  public SpringApplication(Object... sources) {    initialize(sources);  }  private void initialize(Object[] sources) {    if (sources != null && sources.length > 0) {      this.sources.addAll(Arrays.asList(sources));    }    this.webEnvironment = deduceWebEnvironment();    setInitializers((Collection) getSpringFactoriesInstances(        ApplicationContextInitializer.class));    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));    this.mainApplicationClass = deduceMainApplicationClass();  }

SpringApplication

启动SpringBoot项目,我们这里只关注Context创建和实例化AutoConfig相关的逻辑。注意我们的示例不是Web项目,只是个普通的java项目。

run

这里主要有三处,一个是createApplicationContext,一个是prepareContext,一个是refreshContext。

public ConfigurableApplicationContext run(String... args) {    //...    ConfigurableApplicationContext context = null;    //。。。    listeners.starting();    try {      //....      //注意这部分  创建context      context = createApplicationContext();      analyzers = new FailureAnalyzers(context);      prepareContext(context, environment, listeners, applicationArguments,          printedBanner);      //刷新context(实例化各种post以及Bean)      refreshContext(context);      afterRefresh(context, applicationArguments);      // ...      return context;    }    catch (Throwable ex) {    }  }

后边再讲refreshContext。

createApplicationContext

创建Context,我们不是web项目哦。所以我们Context是AnnotationConfigApplicationContext类型。

public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."      + "annotation.AnnotationConfigApplicationContext";  protected ConfigurableApplicationContext createApplicationContext() {    Class> contextClass = this.applicationContextClass;    if (contextClass == null) {      try {        //前边我们分析到,不是web 环境!!所以我们Context是AnnotationConfigApplicationContext类型。        contextClass = Class.forName(this.webEnvironment            ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS);      }      catch (ClassNotFoundException ex) {      //      }    }//这里实例化的是 AnnotationConfigApplicationContext类(无参构造)    return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);  }

AnnotationConfigApplicationContext

类图

我们先看下类图。

db6719201a157b4f25803d1490cd3ca9.png

  • 是BeanDefinitionRegistry

  • 是BeanFactory

  • 是Resource

AnnotationConfigApplicationContext()

从前边我们了解到,我们的context是AnnotationConfigApplicationContext,无参构造会实例化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner。因为Autoconfig相关的都会被@Configuration修饰,所以我们只关注AnnotatedBeanDefinitionReader,它是注解BeanDefinition读取器。我们主要分析说明的是这个。

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

AnnotatedBeanDefinitionReader

AnnotatedBeanDefinitionReader(BeanDefinitionRegistry)

AnnotationConfigApplicationContext就是一个BeanDefinitionRegistry实例。将AnnotationConfigApplicationContext的实例传递到AnnotatedBeanDefinitionReader中使用。下边我们分析这个AnnotatedBeanDefinitionReader类实例化过程中都做了什么。

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {    this(registry, getOrCreateEnvironment(registry));  }  public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");    Assert.notNull(environment, "Environment must not be null");    this.registry = registry;    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);  }

AnnotationConfigUtils

registerAnnotationConfigProcessors

注册注解相关的后置处理器,比如ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor、EventListenerMethodProcessor、DefaultEventListenerFactory等。我们这里只关注配置类相关的源码部分。

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {    registerAnnotationConfigProcessors(registry, null);  }  public static Set registerAnnotationConfigProcessors(      BeanDefinitionRegistry registry, Object source) {    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);    Set beanDefs = new LinkedHashSet(4);    // 注册ConfigurationClassPostProcessor处理器     if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {      RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);      def.setSource(source);      beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));    }    return beanDefs;  }

ConfigurationClassPostProcessor

类图

b6b5e4439fde6453225c3b838f7e691f.png

  • 是BeanDefinitionRegistryPostProcessor

  • 是BeanFactoryPostProcessor

  • 是PriorityOrdered

  • 上边两个接口,是关键,后边要用到!!!!

registerPostProcessor

注册ConfigurationClassPostProcessor处理器到BeanFactory中。

private static BeanDefinitionHolder registerPostProcessor(      BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {    definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);    registry.registerBeanDefinition(beanName, definition);    return new BeanDefinitionHolder(definition, beanName);  }
BeanDefinitionRegistry

从入口处我们知道,registry是AnnotationConfigApplicationContext的实例,被传递过来。它的父类是GenericApplicationContext。在无参实例化时,GenericApplicationContext会持有一个DefaultListableBeanFactory对象。

  • 结构图

 be77769ce60eb7738ca66b900a8a0fa1.png

  • BeanFactory

GenericApplicationContext的实例化BeanFactory过程

private final DefaultListableBeanFactory beanFactory;  public GenericApplicationContext() {    this.beanFactory = new DefaultListableBeanFactory();  }  public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)      throws BeanDefinitionStoreException {    this.beanFactory.registerBeanDefinition(beanName, beanDefinition);  }

DefaultListableBeanFactory

registerBeanDefinition

将BeanDefinition定义交给BeanFactory管理。主要在beanDefinitionMap、beanDefinitionNames这几个map对象中存储。

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)      throws BeanDefinitionStoreException {    Assert.hasText(beanName, "Bean name must not be empty");    Assert.notNull(beanDefinition, "BeanDefinition must not be null");    if (beanDefinition instanceof AbstractBeanDefinition) {      try {        ((AbstractBeanDefinition) beanDefinition).validate();      }      catch (BeanDefinitionValidationException ex) {        throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,            "Validation of bean definition failed", ex);      }    }    BeanDefinition oldBeanDefinition;    oldBeanDefinition = this.beanDefinitionMap.get(beanName);    if (oldBeanDefinition != null) {      if (!isAllowBeanDefinitionOverriding()) {        throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,            "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +            "': There is already [" + oldBeanDefinition + "] bound.");      }      else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {        // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE        if (this.logger.isWarnEnabled()) {          this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +              "' with a framework-generated bean definition: replacing [" +              oldBeanDefinition + "] with [" + beanDefinition + "]");        }      }      else if (!beanDefinition.equals(oldBeanDefinition)) {        if (this.logger.isInfoEnabled()) {          this.logger.info("Overriding bean definition for bean '" + beanName +              "' with a different definition: replacing [" + oldBeanDefinition +              "] with [" + beanDefinition + "]");        }      }      else {        if (this.logger.isDebugEnabled()) {          this.logger.debug("Overriding bean definition for bean '" + beanName +              "' with an equivalent definition: replacing [" + oldBeanDefinition +              "] with [" + beanDefinition + "]");        }      }      this.beanDefinitionMap.put(beanName, beanDefinition);    }    else {      if (hasBeanCreationStarted()) {        // Cannot modify startup-time collection elements anymore (for stable iteration)        synchronized (this.beanDefinitionMap) {          this.beanDefinitionMap.put(beanName, beanDefinition);          List updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);          updatedDefinitions.addAll(this.beanDefinitionNames);          updatedDefinitions.add(beanName);          this.beanDefinitionNames = updatedDefinitions;          if (this.manualSingletonNames.contains(beanName)) {            Set updatedSingletons = new LinkedHashSet(this.manualSingletonNames);            updatedSingletons.remove(beanName);            this.manualSingletonNames = updatedSingletons;          }        }      }      else {        // Still in startup registration phase        this.beanDefinitionMap.put(beanName, beanDefinition);        this.beanDefinitionNames.add(beanName);        this.manualSingletonNames.remove(beanName);      }      this.frozenBeanDefinitionNames = null;    }    if (oldBeanDefinition != null || containsSingleton(beanName)) {      resetBeanDefinition(beanName);    }  }

至此ConfigurationClassPostProcessor已经被BeanFactory管理起来。下边我们再来分析后边这个对象是怎么使用。那么我们再次回到SpringApplication的Run方法中prepareContext和**refreshContext(context);**部分。

SpringApplication

prepareContext

我们重点关注下load部分,传入的是当前启动类。source是new SpringApplication时传入的Class对象,也就是SBStarter.class。

private void prepareContext(ConfigurableApplicationContext context,      ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,      ApplicationArguments applicationArguments, Banner printedBanner) {    //。。。。。    // Load the sources    Set sources = getSources();    Assert.notEmpty(sources, "Sources must not be empty");    load(context, sources.toArray(new Object[sources.size()]));    // 。。。。  }
load

加载bean到ApplicationContext中.BeanDefinitionLoader是持有Context对象的。Context本身就是个registry.

protected void load(ApplicationContext context, Object[] sources) {    if (logger.isDebugEnabled()) {      logger.debug(          "Loading source " + StringUtils.arrayToCommaDelimitedString(sources));    }    BeanDefinitionLoader loader = createBeanDefinitionLoader(        getBeanDefinitionRegistry(context), sources);    if (this.beanNameGenerator != null) {      loader.setBeanNameGenerator(this.beanNameGenerator);    }    if (this.resourceLoader != null) {      loader.setResourceLoader(this.resourceLoader);    }    if (this.environment != null) {      loader.setEnvironment(this.environment);    }    loader.load();  }

BeanDefinitionLoader

load

我们的source就是SBStarter.class,也就是会执行load((Class>) source)。最后注册成类型AnnotatedBeanDefinition的BeanDefinition。

public int load() {    int count = 0;    for (Object source : this.sources) {      count += load(source);    }    return count;  }  private int load(Object source) {    Assert.notNull(source, "Source must not be null");    if (source instanceof Class>) {      return load((Class>) source);    }    if (source instanceof Resource) {      return load((Resource) source);    }    if (source instanceof Package) {      return load((Package) source);    }    if (source instanceof CharSequence) {      return load((CharSequence) source);    }    throw new IllegalArgumentException("Invalid source type " + source.getClass());  }  private int load(Class> source) {    if (isGroovyPresent()) {      // Any GroovyLoaders added in beans{} DSL can contribute beans here      if (GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {        GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source,            GroovyBeanDefinitionSource.class);        load(loader);      }    }    //如果SBStarter是个组件的话,会注册到beanDefinition上去。    if (isComponent(source)) {      //AnnotatedBeanDefinitionReader是前边实例化时创建。目的是注册一个类型AnnotatedBeanDefinition的BeanDefinition      this.annotatedReader.register(source);      return 1;    }    return 0;  }
isComponent
  • @SpringBootApplication是SpringBootConfiguration类型的。

d43e3fb7d7692056141ec96229bacb26.png

  • SpringBootConfiguration是Configuration类型的。

43a62c74595a8bc9b39bd2dbd4f801c8.png

  • Configuration是Component类型的

aeb145729cbd5e8963c9121c9bc09e29.png

  • 最后SBStarter也就是个Component类型的

AnnotatedBeanDefinitionReader

register
//annotatedClasses=com.baigt.sb.SBStarter  public void register(Class>... annotatedClasses) {    for (Class> annotatedClass : annotatedClasses) {      registerBean(annotatedClass);    }  }
registerBean

这里我们要注意的是我们是创建了一个AnnotatedGenericBeanDefinition类型的BeanDefinition对象通过BeanDefinitionReaderUtils工具进行注册的。

public void registerBean(Class> annotatedClass) {    registerBean(annotatedClass, null, (Class extends Annotation>[]) null);  }  public void registerBean(Class> annotatedClass, Class extends Annotation>... qualifiers) {    registerBean(annotatedClass, null, qualifiers);  }  public void registerBean(Class> annotatedClass, String name, Class extends Annotation>... qualifiers) {    //注意这里,我是一个AnnotatedGenericBeanDefinition类型的BeanDefinition实例    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {      return;    }    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);    abd.setScope(scopeMetadata.getScopeName());    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);    if (qualifiers != null) {      for (Class extends Annotation> qualifier : qualifiers) {        if (Primary.class == qualifier) {          abd.setPrimary(true);        }        else if (Lazy.class == qualifier) {          abd.setLazyInit(true);        }        else {          abd.addQualifier(new AutowireCandidateQualifier(qualifier));        }      }    }    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);    //我是在这里和context关联上的    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);  }

BeanDefinitionReaderUtils

registerBeanDefinition

注意传入的registry,AnnotationConfigApplicationContext本身就是个BeanDefinitionRegistry。而这个部分最后调用的是AnnotationConfigApplicationContext在实例化中隐式实例化父类GenericApplicationContext时创建的一个DefaultListableBeanFactory对象的registerBeanDefinition方法。这就又回到了ConfiguationClassPostProcessor时registerBeanDefinition的过程。因此这里就不再继续深入分析。最终的结果是交给了BeanFactory统一管理BeanDefinition!!

public static void registerBeanDefinition(      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)      throws BeanDefinitionStoreException {    // Register bean definition under primary name.    String beanName = definitionHolder.getBeanName();    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());    // Register aliases for bean name, if any.    String[] aliases = definitionHolder.getAliases();    if (aliases != null) {      for (String alias : aliases) {        registry.registerAlias(beanName, alias);      }    }  }

SpringApplication

refreshContext

刷新Context和注册关机钩子;注意传入的是一个AnnotationConfigApplicationContext实例。我们主要分析refresh

private void refreshContext(ConfigurableApplicationContext context) {    refresh(context);    if (this.registerShutdownHook) {      try {        context.registerShutdownHook();      }      catch (AccessControlException ex) {        // Not allowed in some environments.      }    }  }  protected void refresh(ApplicationContext applicationContext) {    Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);    ((AbstractApplicationContext) applicationContext).refresh();  }

刷新用的是AbstractApplicationContext中的refresh方法。

AbstractApplicationContext

org.springframework.context.support.AbstractApplicationContext

refresh

在ConfigurationClassPostProcessor那一部分,我们知道它是一个BeanFactoryPostProcessor。所以我们一定要看的是invokeBeanFactoryPostProcessors部分的逻辑,其次因为Configuration注解类中相关的如@Bean修饰的方法也是要实例化的,所以我们还要看的是finishBeanFactoryInitialization中的逻辑。

public void refresh() throws BeansException, IllegalStateException {    synchronized (this.startupShutdownMonitor) {      // refresh的前置准备,比如设置startTime,开启激活状态、关闭close状态等等等      prepareRefresh();      //告诉子类去刷新内容Bean工厂(从类图中可以明显看出来入口类实例也是个bean工厂)      // 观察和刷新BeanFactory      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();      //提前设置一些在该context中使用的属性,比如Classloader、Callback、environment等      prepareBeanFactory(beanFactory);      try {        // 通知context子类,后置处理beanFactory。比如用一系列的Webcontext子类        postProcessBeanFactory(beanFactory);        // 将BeanFactoryPostProcessor在当前Context中注册为Bean        invokeBeanFactoryPostProcessors(beanFactory);        // 注册BeanPostProcessor来拦截Bean创建的后置处理。        registerBeanPostProcessors(beanFactory);        // 为当前Context初始化MessageSource        initMessageSource();        // 为当前context初始化应用事件广播        initApplicationEventMulticaster();        // 初始化其他特殊的bean对象 比如webcontext        onRefresh();        // 检查监听Bean 并发布他们(ApplicationListener)        registerListeners();        // 实例化BeanFactory中所有的其他的单例对象集合(非延迟的)        finishBeanFactoryInitialization(beanFactory);        // 最后发布LifecycleProcessor和ContextRefreshedEvent事件        finishRefresh();      }      catch (BeansException ex) {        if (logger.isWarnEnabled()) {          logger.warn("Exception encountered during context initialization - " +              "cancelling refresh attempt: " + ex);        }        // 失败销毁bean        destroyBeans();        // Reset 'active' flag.        cancelRefresh(ex);        // Propagate exception to caller.        throw ex;      }      finally {        // Reset common introspection caches in Spring's core, since we        // might not ever need metadata for singleton beans anymore...        resetCommonCaches();      }    }  }
invokeBeanFactoryPostProcessors

使用委托模式来执行BeanFactoryPostProcessors。注意委托类PostProcessorRegistrationDelegate接收的beanFactory是我们的Context实例(是个BeanFactory,同时它也持有ConfigurationClassPostProcessor的BeanDefinition信息)。getBeanFactoryPostProcessors部分中的BeanFactoryPostProcessors是其他步骤中注入的后置器,我们这里不关注。直接进委托类中继续 分析。

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

PostProcessorRegistrationDelegate

org.springframework.context.support.PostProcessorRegistrationDelegate

invokeBeanFactoryPostProcessors

我们不关注beanFactoryPostProcessors部分传入的参数,因为ConfigurationClassPostProcessor不在此。前边我们分析到ConfigurationClassPostProcessor同时是一个BeanDefinitionRegistryPostProcessor,invokeBeanFactoryPostProcessors中与此有关的逻辑我们重点看下!!!

  • 首先执行实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor

  • 其次执行实现Ordered接口的BeanDefinitionRegistryPostProcessor

  • 最后执行其他所有的BeanDefinitionRegistryPostProcessor对象

public static void invokeBeanFactoryPostProcessors(      ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {    // Invoke BeanDefinitionRegistryPostProcessors first, if any.    Set processedBeans = new HashSet();    if (beanFactory instanceof BeanDefinitionRegistry) {      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;      List regularPostProcessors = new LinkedList();      List registryProcessors = new LinkedList();      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {        //省略      }      List currentRegistryProcessors = new ArrayList();      // 首先执行一个实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessors!!! 这不就是我们的ConfigurationClassPostProcessor嘛!!!      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);      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);      currentRegistryProcessors.clear();      // 其次执行一个实现Ordered接口的BeanDefinitionRegistryPostProcessors!!! 且没有在processedBeans中      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();      // 最后执行其他 BeanDefinitionRegistryPostProcessor      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.      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 priorityOrderedPostProcessors = new ArrayList();    List orderedPostProcessorNames = new ArrayList();    List 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 orderedPostProcessors = new ArrayList();    for (String postProcessorName : orderedPostProcessorNames) {      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));    }    sortPostProcessors(orderedPostProcessors, beanFactory);    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);    // Finally, invoke all other BeanFactoryPostProcessors.    List nonOrderedPostProcessors = new ArrayList();    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();  }
  • 我们只关注第一个,因为ConfigurationClassPostProcessor实现了PriorityOrdered接口!!!!

invokeBeanDefinitionRegistryPostProcessors

传入的postProcessors是ConfigurationClassPostProcessor,传入的registry则是我们的AnnotationConfigApplicationContext(前边也提到了他也是个BeanDefinitionRegistry)。哇偶!终于到了我们ConfigurationClassPostProcessor的源码部分了(postProcessBeanDefinitionRegistry)

private static void invokeBeanDefinitionRegistryPostProcessors(      Collection extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {      postProcessor.postProcessBeanDefinitionRegistry(registry);    }  }

ConfigurationClassPostProcessor

postProcessBeanDefinitionRegistry

这个方法比较简单,有些检查,核心方法是processConfigBeanDefinitions。我们跟进去看下。

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);    }    if (this.factoriesPostProcessed.contains(registryId)) {      throw new IllegalStateException(          "postProcessBeanFactory already called on this post-processor against " + registry);    }    this.registriesPostProcessed.add(registryId);    processConfigBeanDefinitions(registry);  }
processConfigBeanDefinitions

类的Doc说明是构建和验证由Configuration注解修饰的Class对象。注意注入的BeanDefinitionRegistry是一个DefaultListableBeanFactory实例,因此也是一个SingletonBeanRegistry对象。具体可自行分析类图的继承关系。这里会加载我们启动类SBStarter这个配置类。

启动类SBStarter是我们自定义的类,是在org.springframework.boot.SpringApplication#prepareContext步骤中注入的。

a956f430f15f06f45800487cd00ef88d.png

/**   * Build and validate a configuration model based on the registry of   * {@link Configuration} classes.   */  public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {    List configCandidates = new ArrayList();    String[] candidateNames = registry.getBeanDefinitionNames();    for (String beanName : candidateNames) {      BeanDefinition beanDef = registry.getBeanDefinition(beanName);      //是否已经加载过      if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||          ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {      }      //没有加载过 就放入configCandidates集合中  这里只有我们手写的启动类SBStarter是没有被加载过的。具体加载过程上边我们已经说过了  我们这里看下SBStarter的后续操作。      else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {        configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));      }    }    // 没有就快速返回    if (configCandidates.isEmpty()) {      return;    }    // 根据Order排序    Collections.sort(configCandidates, new Comparator() {      @Override      public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {        int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());        int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());        return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;      }    });    // Detect any custom bean name generation strategy supplied through the enclosing application context    SingletonBeanRegistry sbr = null;    if (registry instanceof SingletonBeanRegistry) {      sbr = (SingletonBeanRegistry) registry;      if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {        BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);        this.componentScanBeanNameGenerator = generator;        this.importBeanNameGenerator = generator;      }    }    // 解析每一个 @Configuration class  这里只解析到我们开启SpringBootApplication注解的SBStarter类是Configuration class,我们写的那个不在扫描路径中。    ConfigurationClassParser parser = new ConfigurationClassParser(        this.metadataReaderFactory, this.problemReporter, this.environment,        this.resourceLoader, this.componentScanBeanNameGenerator, registry);    Set candidates = new LinkedHashSet(configCandidates);    Set alreadyParsed = new HashSet(configCandidates.size());    do {      //从SBStarter为入口解析Configuration相关Class      parser.parse(candidates);      parser.validate();      Set configClasses = new LinkedHashSet(parser.getConfigurationClasses());      configClasses.removeAll(alreadyParsed);      // Read the model and create bean definitions based on its content      if (this.reader == null) {        this.reader = new ConfigurationClassBeanDefinitionReader(            registry, this.sourceExtractor, this.resourceLoader, this.environment,            this.importBeanNameGenerator, parser.getImportRegistry());      }      // 在这里加载成BeanDefinition 并交给BeanFactory管理。      this.reader.loadBeanDefinitions(configClasses);      alreadyParsed.addAll(configClasses);      candidates.clear();      if (registry.getBeanDefinitionCount() > candidateNames.length) {        String[] newCandidateNames = registry.getBeanDefinitionNames();        Set oldCandidateNames = new HashSet(Arrays.asList(candidateNames));        Set alreadyParsedClasses = new HashSet();        for (ConfigurationClass configurationClass : alreadyParsed) {          alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());        }        for (String candidateName : newCandidateNames) {          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());    // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes    if (sbr != null) {      if (!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(set)

这里主要分析两个部分,一个是再次Parse(不同入参),一个是完整流程(processDeferredImportSelectors())

  • SBStarter注入的BeanDefiniton是个AnnotatedBeanDefinition

触发parse(AnnotationMetadata metadata, String beanName)调用

public void parse(Set configCandidates) {    this.deferredImportSelectors = new LinkedList();    for (BeanDefinitionHolder holder : configCandidates) {      BeanDefinition bd = holder.getBeanDefinition();      try {        if (bd instanceof AnnotatedBeanDefinition) {          parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());        }        else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {          parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());        }        else {          parse(bd.getBeanClassName(), holder.getBeanName());        }      }      catch (BeanDefinitionStoreException ex) {        throw ex;      }      catch (Throwable ex) {        throw new BeanDefinitionStoreException(            "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);      }    }    processDeferredImportSelectors();  }
parse(AnnotationMetadata, String)
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {    processConfigurationClass(new ConfigurationClass(metadata, beanName));  }
processConfigurationClass

处理ConfigurationClass对象。主要是doProcessConfigurationClass部分。

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {    if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {      return;    }    ConfigurationClass existingClass = this.configurationClasses.get(configClass);    if (existingClass != null) {      if (configClass.isImported()) {        if (existingClass.isImported()) {          existingClass.mergeImportedBy(configClass);        }        // Otherwise ignore new imported config class; existing non-imported class overrides it.        return;      }      else {        // Explicit bean definition found, probably replacing an import.        // Let's remove the old one and go with the new one.        this.configurationClasses.remove(configClass);        for (Iterator it = this.knownSuperclasses.values().iterator(); it.hasNext();) {          if (configClass.equals(it.next())) {            it.remove();          }        }      }    }    // Recursively process the configuration class and its superclass hierarchy.    SourceClass sourceClass = asSourceClass(configClass);    do {      sourceClass = doProcessConfigurationClass(configClass, sourceClass);    }    while (sourceClass != null);    this.configurationClasses.put(configClass, configClass);  }
doProcessConfigurationClass

这里很重要了,也是很复杂的一部分。不过也是SpringBoot可以不使用Xml就能扫描注解相关类的关键部分。下边大概涉及到@PropertySources,@PropertySource,@ComponentScans.class, @ComponentScan.class,@Import,@ImportSource等等。我们主要关注的是@Import部分。为什么?因为我们还是目的就是想看@EnableAutoConfiguration是怎么加载不同目录下的配置类,并实例化的!!! 而在@EnableAutoConfiguration中有使用了@Import,@Import(EnableAutoConfigurationImportSelector.class)

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)      throws IOException {    // 处理成员class  比如内部class 静态class    processMemberClasses(configClass, sourceClass);    // 处理 @PropertySource annotations    for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(        sourceClass.getMetadata(), PropertySources.class,        org.springframework.context.annotation.PropertySource.class)) {      if (this.environment instanceof ConfigurableEnvironment) {        processPropertySource(propertySource);      }      else {        logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +            "]. Reason: Environment must implement ConfigurableEnvironment");      }    }    // 处理 @ComponentScan annotations    Set componentScans = AnnotationConfigUtils.attributesForRepeatable(        sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);    if (!componentScans.isEmpty() &&        !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {      for (AnnotationAttributes componentScan : componentScans) {        // The config class is annotated with @ComponentScan -> perform the scan immediately        Set scannedBeanDefinitions =            this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());        // Check the set of scanned definitions for any further config classes and parse recursively if needed        for (BeanDefinitionHolder holder : scannedBeanDefinitions) {          BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();          if (bdCand == null) {            bdCand = holder.getBeanDefinition();          }          if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {            parse(bdCand.getBeanClassName(), holder.getBeanName());          }        }      }    }    // 处理 any @Import annotations  我们Spring.factories就是在这一部分  会解析出org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector    processImports(configClass, sourceClass, getImports(sourceClass), true);    // 处理 any @ImportResource annotations  如果手动引入了xml配置文件 基本是这种的    if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {      AnnotationAttributes importResource =          AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);      String[] resources = importResource.getStringArray("locations");      Class extends BeanDefinitionReader> readerClass = importResource.getClass("reader");      for (String resource : resources) {        String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);        configClass.addImportedResource(resolvedResource, readerClass);      }    }    // Process individual @Bean methods    Set beanMethods = retrieveBeanMethodMetadata(sourceClass);    for (MethodMetadata methodMetadata : beanMethods) {      configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));    }    // Process default methods on interfaces    processInterfaces(configClass, sourceClass);    // Process superclass, if any    if (sourceClass.getMetadata().hasSuperClass()) {      String superclass = sourceClass.getMetadata().getSuperClassName();      if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {        this.knownSuperclasses.put(superclass, configClass);        // Superclass found, return its annotation metadata and recurse        return sourceClass.getSuperClass();      }    }    // No superclass -> processing is complete    return null;  }
processImports

从EnableAutoConfigurationImportSelector中获取Spring.factories中key=org.springframework.boot.autoconfigure.EnableAutoConfiguration的需要自动化加载的配置类。最后存放在deferredImportSelectors集合中。

9fbcf3602edb129573725b5f9d9bbe57.png

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,      Collection importCandidates, boolean checkForCircularImports) {    if (importCandidates.isEmpty()) {      return;    }    if (checkForCircularImports && isChainedImportOnStack(configClass)) {      this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));    }    else {      this.importStack.push(configClass);      try {        for (SourceClass candidate : importCandidates) {          if (candidate.isAssignable(ImportSelector.class)) {            // Candidate class is an ImportSelector -> delegate to it to determine imports            Class> candidateClass = candidate.loadClass();            //实例化EnableAutoConfigurationImportSelector  存放在deferredImportSelectors中            ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);            ParserStrategyUtils.invokeAwareMethods(                selector, this.environment, this.resourceLoader, this.registry);            if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {              this.deferredImportSelectors.add(                  new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));            }            else {              String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());              Collection importSourceClasses = asSourceClasses(importClassNames);              processImports(configClass, currentSourceClass, importSourceClasses, false);            }          }          else {          //省略代码          }        }      }      catch (BeanDefinitionStoreException ex) {        //      }      finally {        this.importStack.pop();      }    }  }
parse(Set configCandidates)

返回到此处,执行 processDeferredImportSelectors方法。处理刚才存放在deferredImportSelectors中的import对象。

public void parse(Set configCandidates) {    this.deferredImportSelectors = new LinkedList();    for (BeanDefinitionHolder holder : configCandidates) {      BeanDefinition bd = holder.getBeanDefinition();      try {        if (bd instanceof AnnotatedBeanDefinition) {          parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());        }        else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {          parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());        }        else {          parse(bd.getBeanClassName(), holder.getBeanName());        }      }      catch (BeanDefinitionStoreException ex) {        throw ex;      }    }    //处理我们刚才存放在这里的deferredImportSelectors    processDeferredImportSelectors();  }
processDeferredImportSelectors

调用ImportSelector类的selectImports方法,最后递归调用processImports来处理其他Configuration类。这里我们来看下EnableAutoConfigurationImportSelector的selectImports方法。

private void processDeferredImportSelectors() {    List deferredImports = this.deferredImportSelectors;    this.deferredImportSelectors = null;    Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR);    for (DeferredImportSelectorHolder deferredImport : deferredImports) {      ConfigurationClass configClass = deferredImport.getConfigurationClass();      try {        String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata());        processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false);      }      catch (BeanDefinitionStoreException ex) {      }    }  }

EnableAutoConfigurationImportSelector

@EnableAutoConfiguration 中@Import引入的ImportSelector。我们Ctrl+F12来看下selectImports方法在哪?

dbeb56e6c8fd191d6ec1f3f11ec98256.png

AutoConfigurationImportSelector

EnableAutoConfigurationImportSelector 的父类。selectImports方法所在的类。我们重点关注getCandidateConfigurations方法的源码。通过SpringFactoriesLoader.loadFactoryNames来加载spring.factories中对应key为EnableAutoConfiguration的ConfigClass集合。

public String[] selectImports(AnnotationMetadata annotationMetadata) {    //如果不是EnableAutoConfigurationImportSelector的时候 isEnabled==true  默认AutoConfigurationImportSelector的isEnable==true ,走后边的逻辑    if (!isEnabled(annotationMetadata)) {      return NO_IMPORTS;    }    try {      AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader          .loadMetadata(this.beanClassLoader);      AnnotationAttributes attributes = getAttributes(annotationMetadata);      //获取需要自动化加载配置类 这个是核心类。我们下边分析      List configurations = getCandidateConfigurations(annotationMetadata,          attributes);      //删除重复的configClass          configurations = removeDuplicates(configurations);      //排序      configurations = sort(configurations, autoConfigurationMetadata);      Set exclusions = getExclusions(annotationMetadata, attributes);      //删除exclue掉的Class      checkExcludedClasses(configurations, exclusions);      configurations.removeAll(exclusions);      //处理AutoConfigurationImportFilter      configurations = filter(configurations, autoConfigurationMetadata);      //处理AutoConfigurationImportListener      fireAutoConfigurationImportEvents(configurations, exclusions);      return configurations.toArray(new String[configurations.size()]);    }    catch (IOException ex) {      throw new IllegalStateException(ex);    }  }  // 通过SpringFactoriesLoader加载EnableAutoConfiguration相关的配置类  protected List getCandidateConfigurations(AnnotationMetadata metadata,      AnnotationAttributes attributes) {    List configurations = SpringFactoriesLoader.loadFactoryNames(        getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());    Assert.notEmpty(configurations,        "No auto configuration classes found in META-INF/spring.factories. If you "            + "are using a custom packaging, make sure that file is correct.");    return configurations;  }  // 要通过SpringFactories来加载的类  protected Class> getSpringFactoriesLoaderFactoryClass() {    return EnableAutoConfiguration.class;  }

SpringFactoriesLoader

loadFactoryNames

//从META-INF/spring.factories的文件中解析内容(所有的spring.factories。包括spring-boot-1.5.14.RELEASE.jar中的)。从中拿到org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置类,比如我们自己定义的BaigtAutoConfig类。

8dbde639bc563088c4502e96cf12ae87.png

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";  public static List loadFactoryNames(Class> factoryClass, ClassLoader classLoader) {    //factoryClassName=org.springframework.boot.autoconfigure.EnableAutoConfiguration    String factoryClassName = factoryClass.getName();    try {      //从META-INF/spring.factories的文件中解析内容(所有的spring.factories。包括spring-boot-1.5.14.RELEASE.jar中的)      Enumeration urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :          ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));      List result = new ArrayList();      while (urls.hasMoreElements()) {        URL url = urls.nextElement();        //转换为Properties        Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));        //从properties中获取EnableAutoConfiguration对应的Value  比如我们的com.baigt.autoconfig.BaigtAutoConfig        String factoryClassNames = properties.getProperty(factoryClassName);        result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));      }      return result;    }    catch (IOException ex) {    }  }

接下来我们返回到ConfigurationClassPostProcessor的processConfigBeanDefinitions方法。

ConfigurationClassPostProcessor

processConfigBeanDefinitions

接下来我们来看下**this.reader.loadBeanDefinitions(configClasses);**加载我们配置类,交给beanFactory管理。

dfa2236bc5268f01a124a215772bb112.png

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {    List configCandidates = new ArrayList();    String[] candidateNames = registry.getBeanDefinitionNames();    //。。。。    // Parse each @Configuration class    ConfigurationClassParser parser = new ConfigurationClassParser(        this.metadataReaderFactory, this.problemReporter, this.environment,        this.resourceLoader, this.componentScanBeanNameGenerator, registry);    Set candidates = new LinkedHashSet(configCandidates);    Set alreadyParsed = new HashSet(configCandidates.size());    do {      parser.parse(candidates);      parser.validate();      Set configClasses = new LinkedHashSet(parser.getConfigurationClasses());      configClasses.removeAll(alreadyParsed);      // Read the model and create bean definitions based on its content      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);  }

ConfigurationClassBeanDefinitionReader

loadBeanDefinitions

我们只关注我们定义的配置类(BaigtAutoConfig)

public void loadBeanDefinitions(Set configurationModel) {    TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();    for (ConfigurationClass configClass : configurationModel) {      loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);    }  }
loadBeanDefinitionsForConfigurationClass

处理配置类中上的注解(比如Import),以及@Bean方法

ac9235b467dce2024f1f22d97c8ec17f.png

private void loadBeanDefinitionsForConfigurationClass(      ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {    if (trackedConditionEvaluator.shouldSkip(configClass)) {      String beanName = configClass.getBeanName();      if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {        this.registry.removeBeanDefinition(beanName);      }      this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());      return;    }    // BaigtAutoConfig是通过Import(SelectImports)来创建的ConfigClass  所以这里是true    if (configClass.isImported()) {      //将该配置类注册为BeanDefinition      registerBeanDefinitionForImportedConfigurationClass(configClass);    }    // BaigtAutoConfig中有个@Bean修饰的方法 也会执行这个方法    for (BeanMethod beanMethod : configClass.getBeanMethods()) {      loadBeanDefinitionsForBeanMethod(beanMethod);    }    //配置类中如果使用了ImportSource注解和ImportBeanDefinitionRegistrar。则去加载相关内容成BeanDefinition    loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());    loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());  }
registerBeanDefinitionForImportedConfigurationClass

将BaigtAutoConfig配置类注册为BeanDefinition

3bb3f374bcce4bb24d0e20ed376b1b01.png

private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {    AnnotationMetadata metadata = configClass.getMetadata();    AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);    ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);    configBeanDef.setScope(scopeMetadata.getScopeName());    String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);    AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);    // 注册我们的BaigtAutoConfig    this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());    configClass.setBeanName(configBeanName);  }
loadBeanDefinitionsForBeanMethod

f8e7a9d3497af241a533a6eb30b0d00f.png

解析@Bean方法中相关的属性,比如设置factoryMethod、InitMethod、DestroyMethod、beanName、alias等。也设置lazy、dependOn等等。最后this.registry.registerBeanDefinition(beanName, beanDefToRegister); 完成配置类中@Bean方法的注册。this.registry又是我们前边提到的DefaultListableBeanFactory。交给BeanFactory管理。

private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {    ConfigurationClass configClass = beanMethod.getConfigurationClass();    MethodMetadata metadata = beanMethod.getMetadata();    String methodName = metadata.getMethodName();    // 这一步(shouldSkip)会设置mergedBeanDefinitions中该name的scope为单例。即使没有这个在最后判断的时候scope=""时也等价于单例    if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {      configClass.skippedBeanMethods.add(methodName);      return;    }    if (configClass.skippedBeanMethods.contains(methodName)) {      return;    }    // Consider name and any aliases    AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);    List names = new ArrayList(Arrays.asList(bean.getStringArray("name")));    String beanName = (!names.isEmpty() ? names.remove(0) : methodName);    // Register aliases even when overridden    for (String alias : names) {      this.registry.registerAlias(beanName, alias);    }    // Has this effectively been overridden before (e.g. via XML)?    if (isOverriddenByExistingDefinition(beanMethod, beanName)) {      if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {        throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),            beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +            "' clashes with bean name for containing configuration class; please make those names unique!");      }      return;    }    ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);    beanDef.setResource(configClass.getResource());    beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));    if (metadata.isStatic()) {      // static @Bean method      beanDef.setBeanClassName(configClass.getMetadata().getClassName());      beanDef.setFactoryMethodName(methodName);    }    else {      // instance @Bean method      beanDef.setFactoryBeanName(configClass.getBeanName());      beanDef.setUniqueFactoryMethodName(methodName);    }    beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);    beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);    AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);    Autowire autowire = bean.getEnum("autowire");    if (autowire.isAutowire()) {      beanDef.setAutowireMode(autowire.value());    }    String initMethodName = bean.getString("initMethod");    if (StringUtils.hasText(initMethodName)) {      beanDef.setInitMethodName(initMethodName);    }    String destroyMethodName = bean.getString("destroyMethod");    if (destroyMethodName != null) {      beanDef.setDestroyMethodName(destroyMethodName);    }    // Consider scoping    ScopedProxyMode proxyMode = ScopedProxyMode.NO;    AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);    if (attributes != null) {      beanDef.setScope(attributes.getString("value"));      proxyMode = attributes.getEnum("proxyMode");      if (proxyMode == ScopedProxyMode.DEFAULT) {        proxyMode = ScopedProxyMode.NO;      }    }    // Replace the original bean definition with the target one, if necessary    BeanDefinition beanDefToRegister = beanDef;    if (proxyMode != ScopedProxyMode.NO) {      BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(          new BeanDefinitionHolder(beanDef, beanName), this.registry,          proxyMode == ScopedProxyMode.TARGET_CLASS);      beanDefToRegister = new ConfigurationClassBeanDefinition(          (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);    }    if (logger.isDebugEnabled()) {      logger.debug(String.format("Registering bean definition for @Bean method %s.%s()",          configClass.getMetadata().getClassName(), beanName));    }    this.registry.registerBeanDefinition(beanName, beanDefToRegister);  }

接下来,我们回到 AbstractApplicationContext#refresh

AbstractApplicationContext

refresh
finishBeanFactoryInitialization(beanFactory);
finishBeanFactoryInitialization

通过beanFactory来实例化我们之前交给它管理的BeanDefinition。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//省略一些代码
// 实例化一些单例(non-lazyinit)
beanFactory.preInstantiateSingletons();
}

DefaultListableBeanFactory

preInstantiateSingletons

实例化beanDefinitionNames中定义BeanDefinition的单例。当然也包含我们的BaigtAutoConfig中对应的@Bean(name="baigt")方法的BeanDefinition

c7a39caa96f0cca1d36a7cfb96bb1b8e.png

1bc71a79b24d981d23817dda040941a2.png

public void preInstantiateSingletons() throws BeansException {    // 从我们放入到beanDefinitionNames中来遍历进行实例化。    List beanNames = new ArrayList(this.beanDefinitionNames);    // Trigger initialization of all non-lazy singleton beans...    for (String beanName : beanNames) {      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {        if (isFactoryBean(beanName)) {          final FactoryBean> factory = (FactoryBean>) getBean(FACTORY_BEAN_PREFIX + beanName);          boolean isEagerInit;          if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {            isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {              @Override              public Boolean run() {                return ((SmartFactoryBean>) factory).isEagerInit();              }            }, getAccessControlContext());          }          else {            isEagerInit = (factory instanceof SmartFactoryBean &&                ((SmartFactoryBean>) factory).isEagerInit());          }          if (isEagerInit) {            getBean(beanName);          }        }        else {          // 最后执行这个方法进行实例化          getBean(beanName);        }      }    }    // SmartInitializingSingleton的处理  }

AbstractBeanFactory

getBean
public Object getBean(String name) throws BeansException {    return doGetBean(name, null, null, false);  }
doGetBean

这里我们就是要创建单例的实例(有就从缓存中取)。创建的方式是通过ObjectFactory内部类实现中的createBean方法来完成。我们先看下getSingleton的逻辑。

cde569c2f777c2c466bda1359abf220d.png

// 首次进来为空  最后会走下边的逻辑    Object sharedInstance = getSingleton(beanName);    // 通过this.beanDefinitionMap得到的  具体可自行查看源码。这里不太花篇幅讲述。    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);    //...    if (mbd.isSingleton()) {          sharedInstance = getSingleton(beanName, new ObjectFactory() {            @Override            public Object getObject() throws BeansException {              try {                 //最终创建Bean的逻辑                return createBean(beanName, mbd, args);              }              catch (BeansException ex) {                destroySingleton(beanName);                throw ex;              }            }          });          bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);        }  //....      // 注意这里,会把单例cache起来,在后边可以直接使用  if (newSingleton) {    addSingleton(beanName, singletonObject);  }

DefaultSingletonBeanRegistry

getSingleton

这里我们要分析的核心逻辑(instance singleton)是调用的了ObjectFactory.getObject,即我们上边的内部类,而内部类的实现则是通过createBean完成。我们再来看下createBean的逻辑。

try {          //回到了AbstractBeanFactory#doGetBean的ObjectFactory的getObject方法,执行其中的createBean方法          singletonObject = singletonFactory.getObject();          newSingleton = true;        }

AbstractAutowireCapableBeanFactory

createBean

AbstractBeanFactory的子类实现方法

AbstractAutowireCapableBeanFactory#createBean(java.lang.Class)  public  T createBean(Class beanClass) throws BeansException {    // Use prototype bean definition, to avoid registering bean as dependent bean.    RootBeanDefinition bd = new RootBeanDefinition(beanClass);    bd.setScope(SCOPE_PROTOTYPE);    bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());    return (T) createBean(beanClass.getName(), bd, null);  }// 接上protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {    RootBeanDefinition mbdToUse = mbd;    Class> resolvedClass = resolveBeanClass(mbd, beanName);    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {      mbdToUse = new RootBeanDefinition(mbd);      mbdToUse.setBeanClass(resolvedClass);    }    try {      mbdToUse.prepareMethodOverrides();    }    catch (BeanDefinitionValidationException ex) {    }    try {      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);      if (bean != null) {        return bean;      }    }    catch (Throwable ex) {    }    // 普通Bean的实例创建    Object beanInstance = doCreateBean(beanName, mbdToUse, args);    if (logger.isDebugEnabled()) {      logger.debug("Finished creating instance of bean '" + beanName + "'");    }    return beanInstance;  }
doCreateBean

核心关注instanceWrapper和exposedObject对象的处理过程

436b4bcf0720f532650ef1b76617f834.png

BeanWrapper instanceWrapper = null;    if (mbd.isSingleton()) {      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);    }    if (instanceWrapper == null) {      //创建bean实例的Wrapper对象      instanceWrapper = createBeanInstance(beanName, mbd, args);    }    // bean实例在wrapper中已经创建了(不完整)    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);    //省略一些代码。。。    // Initialize the bean instance.    Object exposedObject = bean;    try {      // 注入property到Bean中      populateBean(beanName, mbd, instanceWrapper);      if (exposedObject != null) {        exposedObject = initializeBean(beanName, exposedObject, mbd);      }    }    //省略一些代码。。。    return exposedObject;
createBeanInstance

instanceWrapper = createBeanInstance(beanName, mbd, args); 该方法是给指定的name的Class创建Bean对象,支持无参、factoryMethod、AutoWireConstructor三种策略。默认执行无参的"instantiateBean"。而我们的BaigtAutoConfig中的@Bean则设置的有FactoryMethodName(我们定义的@Bean的方法名="env")

8b20f91e32e3a774909c29eee955c7ba.png

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {    // Make sure bean class is actually resolved at this point.    Class> beanClass = resolveBeanClass(mbd, beanName);    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {      throw new BeanCreationException(mbd.getResourceDescription(), beanName,          "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());    }    //配置类中的@Bean方法是通过下边这种方式实例化的。    if (mbd.getFactoryMethodName() != null)  {      return instantiateUsingFactoryMethod(beanName, mbd, args);    }    // Shortcut when re-creating the same bean...    boolean resolved = false;    boolean autowireNecessary = false;    if (args == null) {      synchronized (mbd.constructorArgumentLock) {        if (mbd.resolvedConstructorOrFactoryMethod != null) {          resolved = true;          autowireNecessary = mbd.constructorArgumentsResolved;        }      }    }    // 一般我们不是FactoryMethod和有参构造(也可以有哈)    if (resolved) {      if (autowireNecessary) {        return autowireConstructor(beanName, mbd, null, null);      }      else {        return instantiateBean(beanName, mbd);      }    }    // Need to determine the constructor...    Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);    if (ctors != null ||        mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {      return autowireConstructor(beanName, mbd, ctors, args);    }    //没有特殊处理就使用无参构造实例    // No special handling: simply use no-arg constructor.    return instantiateBean(beanName, mbd);  }
instantiateUsingFactoryMethod
protected BeanWrapper instantiateUsingFactoryMethod(      String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {    return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);  }

ConstructorResolver

instantiateUsingFactoryMethod

8d365ecc7390e686b1499218608a09a8.png

BeanWrapperImpl bw = new BeanWrapperImpl();    this.beanFactory.initBeanWrapper(bw);//。。。。Object beanInstance;  beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(            mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);  bw.setBeanInstance(beanInstance);  return bw;

SimpleInstantiationStrategy

instantiate

最后调用@Bean对应的方法的invoke方法。到此配置类中的@Bean已经实例化完成。

b1bcb292a5070b5c778ac1e4dde5bb95.png

public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,      Object factoryBean, final Method factoryMethod, Object... args) {    try {      if (System.getSecurityManager() != null) {        AccessController.doPrivileged(new PrivilegedAction() {          @Override          public Object run() {            ReflectionUtils.makeAccessible(factoryMethod);            return null;          }        });      }      else {        ReflectionUtils.makeAccessible(factoryMethod);      }      Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();      try {        currentlyInvokedFactoryMethod.set(factoryMethod);        //执行方法        return factoryMethod.invoke(factoryBean, args);      }      finally {        if (priorInvokedFactoryMethod != null) {          currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);        }        else {          currentlyInvokedFactoryMethod.remove();        }      }    }    catch (IllegalArgumentException ex) {      throws ex;    }  }

AbstractAutowireCapableBeanFactory

返回到doCreateBean方法

doCreateBean

我们继续看exposedObject处理的内容。装载Bean的Property属性,initBean对象。我们着重看下initializeBean方法。

final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);Object exposedObject = bean;    try {      //装载比如Property属性  可以是其他Bean对象,也可能是String等基本属性。具体见populateBean中的applyPropertyValues方法      populateBean(beanName, mbd, instanceWrapper);      if (exposedObject != null) {        //初始化Bean对象        exposedObject = initializeBean(beanName, exposedObject, mbd);      }    }
initializeBean
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

初始化给定的Bean,(RootBeanDefinition为空时,执行BeanPost)执行wired的相关方法((BeanNameAware、BeanClassLoaderAware、BeanFactoryAware))、执行initMethod。比如InitializingBean#afterPropertiesSet();或者是自定义的init方法。

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {    if (System.getSecurityManager() != null) {      AccessController.doPrivileged(new PrivilegedAction() {        @Override        public Object run() {          invokeAwareMethods(beanName, bean);          return null;        }      }, getAccessControlContext());    }    else {      //执行wire的method(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)      invokeAwareMethods(beanName, bean);    }    Object wrappedBean = bean;    if (mbd == null || !mbd.isSynthetic()) {      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);    }    try {      //执行init方法      invokeInitMethods(beanName, wrappedBean, mbd);    }    catch (Throwable ex) {      throw new BeanCreationException(          (mbd != null ? mbd.getResourceDescription() : null),          beanName, "Invocation of init method failed", ex);    }    if (mbd == null || !mbd.isSynthetic()) {      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);    }    return wrappedBean;  }
invokeInitMethods

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods。执行afterPropertiesSet方法。如果是自定义的init方法,就调用invokeCustomInitMethod。

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)      throws Throwable {    boolean isInitializingBean = (bean instanceof InitializingBean);    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {      if (logger.isDebugEnabled()) {        logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");      }      if (System.getSecurityManager() != null) {        try {          AccessController.doPrivileged(new PrivilegedExceptionAction() {            @Override            public Object run() throws Exception {              ((InitializingBean) bean).afterPropertiesSet();              return null;            }          }, getAccessControlContext());        }        catch (PrivilegedActionException pae) {          throw pae.getException();        }      }      else {        ((InitializingBean) bean).afterPropertiesSet();      }    }    if (mbd != null) {      String initMethodName = mbd.getInitMethodName();      if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&          !mbd.isExternallyManagedInitMethod(initMethodName)) {        invokeCustomInitMethod(beanName, bean, mbd);      }    }  }

AbstractApplicationContext

返回到refresh方法

refresh

至此配置类相关的Bean实例化完成。

// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值