深入理解EnableAutoConfiguration原理

源碼分析@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).
 * <p>
 * When using {@link SpringBootApplication}, the auto-configuration of the context is
 * automatically enabled and adding this annotation has therefore no additional effect.
 * <p>
 * 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.
 * <p>
 * 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.
 * <p>
 * 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 {};

}

類圖

注意“@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"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.baigt</groupId>
    <artifactId>SpringBootCodeAnalyze</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.14.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • BaigtAutoConfig

注意和啓動類不在一個目錄中

package com.baigt.autoconfig;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 測試Autoconfig
 */
@Configuration
public 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加載的流程(加載自定義的配置類,不在同一個目錄中)
 */
@SpringBootApplication
public 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

類圖

我們先看下類圖。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-mnBCr3Vt-1593910393257)(https://gitee.com/bgt0314/vnoteimg/raw/master/1593835963_20200704121238961_5862.png =1066x)]

  • 是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<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(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

類圖

  • 是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對象。

  • 結構圖

  • 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<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					if (this.manualSingletonNames.contains(beanName)) {
						Set<String> updatedSingletons = new LinkedHashSet<String>(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<Object> 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類型的。

  • SpringBootConfiguration是Configuration類型的。

  • Configuration是Component類型的

  • 最後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<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

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

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

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				//省略
			}

		
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();

			// 首先執行一個實現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<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		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<BeanFactoryPostProcessor>();
		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<BeanFactoryPostProcessor>();
		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步驟中注入的。

	/**
	 * Build and validate a configuration model based on the registry of
	 * {@link Configuration} classes.
	 */
	public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
		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<BeanDefinitionHolder>() {
			@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<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
		do {
			//從SBStarter爲入口解析Configuration相關Class
			parser.parse(candidates);
			parser.validate();

			Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(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<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
				Set<String> alreadyParsedClasses = new HashSet<String>();
				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<BeanDefinitionHolder> configCandidates) {
		this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();

		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<ConfigurationClass> 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<AnnotationAttributes> 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<BeanDefinitionHolder> 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<MethodMetadata> 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集合中。

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> 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<SourceClass> 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<BeanDefinitionHolder> configCandidates) {
		this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();

		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<DeferredImportSelectorHolder> 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方法在哪?

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<String> configurations = getCandidateConfigurations(annotationMetadata,
					attributes);
			//刪除重複的configClass		
			configurations = removeDuplicates(configurations);
			//排序
			configurations = sort(configurations, autoConfigurationMetadata);
			Set<String> 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<String> getCandidateConfigurations(AnnotationMetadata metadata,
			AnnotationAttributes attributes) {
		List<String> 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類。

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
	public static List<String> 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<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
					ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
			List<String> result = new ArrayList<String>();
			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管理。

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

		//。。。。
		// Parse each @Configuration class
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
		do {
			parser.parse(candidates);
			parser.validate();

			Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(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<ConfigurationClass> configurationModel) {
		TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
		for (ConfigurationClass configClass : configurationModel) {
			loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
		}
	}

loadBeanDefinitionsForConfigurationClass

處理配置類中上的註解(比如Import),以及@Bean方法

	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

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

解析@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<String> names = new ArrayList<String>(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

public void preInstantiateSingletons() throws BeansException {
		// 從我們放入到beanDefinitionNames中來遍歷進行實例化。
		List<String> beanNames = new ArrayList<String>(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<Boolean>() {
							@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的邏輯。

		// 首次進來爲空  最後會走下邊的邏輯
		Object sharedInstance = getSingleton(beanName);
		// 通過this.beanDefinitionMap得到的  具體可自行查看源碼。這裏不太花篇幅講述。
		final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
		//...
		if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@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<T>)
	public <T> T createBean(Class<T> 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對象的處理過程

	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”)

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

	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已經實例化完成。

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<Object>() {
					@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<Object>() {
				@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<Object>() {
						@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);

其他Bean

我們這裏只關注的是配置類的加載,普通Bean的加載可以看我的另外一篇文章 徹底弄懂Spring中Bean的解析、創建和使用

結語

分析使用的Spring版本爲4.3.18。代碼上如有出入,請自行區分。最後如有不對,歡迎指正。 作者:ricky QQ交流羣:244930845。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章