1. 程式人生 > >Spring5原始碼解析1-從啟動容器開始

Spring5原始碼解析1-從啟動容器開始

@Configuration
@ComponentScan
public class AppConfig {
}

public class Main {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context =
				new AnnotationConfigApplicationContext(AppConfig.class);
		context.close();
	}
}

先來看一下AnnotationConfigApplicationContext類的UML圖,留個印象。

AnnotationConfigApplicationContext

點開AnnotationConfigApplicationContext(AppConfig.class);方法檢視原始碼:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
	//呼叫預設無參構造器,裡面有一大堆初始化邏輯
	this();

	//把傳入的Class進行註冊,Class既可以有@Configuration註解,也可以沒有@Configuration註解
	//怎麼註冊? 委託給了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法進行註冊
	// 傳入Class 生成  BeanDefinition , 然後通過 註冊到 BeanDefinitionRegistry
	register(annotatedClasses);

	//重新整理容器上下文
	refresh();
}

該構造器允許我們傳入一個或者多個class物件。class物件可以是被@Configuration標註的,也可以是一個普通的Java 類。

有參構造器呼叫了無參構造器,點開原始碼:

public AnnotationConfigApplicationContext() {
	//隱式呼叫父類構造器,初始化beanFactory,具體實現類為DefaultListableBeanFactory
	super(); // 這個程式碼是筆者新增的,方便定位到super方法

	//建立 AnnotatedBeanDefinitionReader,
	//建立時會向傳入的 BeanDefinitionRegistry 中 註冊 註解配置相關的 processors 的 BeanDefinition
	this.reader = new AnnotatedBeanDefinitionReader(this);

	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

初始化子類時會先初始化父類,會預設呼叫父類無參構造器。AnnotationConfigApplicationContext繼承了GenericApplicationContext,在GenericApplicationContext的無參構造器中,建立了BeanFactory的具體實現類DefaultListableBeanFactory。spring中的BeanFactory就是在這裡被例項化的,並且使用DefaultListableBeanFactory做的BeanFactory的預設實現。

public GenericApplicationContext() {
	this.beanFactory = new DefaultListableBeanFactory();
}

DefaultListableBeanFactory

AnnotationConfigApplicationContext的構造器中還建立了兩個物件:AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScanner

先說scanner的作用,通過檢視原始碼可以發現,這個scanner只有在手動呼叫AnnotationConfigApplicationContext的一些方法的時候才會被使用(通過後面的原始碼探究也可以發現,spring並不是使用這個scanner來掃描包獲取Bean的)。

scanner

建立AnnotatedBeanDefinitionReader物件。spring在建立reader的時候把this當做了引數傳給了構造器。也就是說,reader物件裡面包含了一個this物件,也就是AnnotationConfigApplicationContext物件。AnnotationConfigApplicationContext 實現了BeanDefinitionRegistry介面。點開this.reader = new AnnotatedBeanDefinitionReader(this);原始碼:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
	this(registry, getOrCreateEnvironment(registry));
}

從傳入的BeanDefinitionRegistry物件,也就是AnnotationConfigApplicationContext物件中獲取Environment(共用同一個Environment),然後又接著呼叫另一個構造器。點開原始碼:

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);
	//在 BeanDefinitionRegistry 中註冊 註解配置相關的 processors
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

在這個構造器中,執行了一個非常重要的方法AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);,顧名思義,spring通過這個方法註冊瞭解析註解配置相關的處理器。點開原始碼:

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
	registerAnnotationConfigProcessors(registry, null);
}
//再點開原始碼
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
		BeanDefinitionRegistry registry, @Nullable Object source) {

	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
	if (beanFactory != null) {
		if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
			beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
		}
		if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
			beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
		}
	}

	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

	if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		//org.springframework.context.annotation.internalConfigurationAnnotationProcessor - ConfigurationClassPostProcessor.class
		//這個類非常的重要,它是一個 BeanDefinitionRegistryPostProcessor
		RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
	if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
	if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition();
		try {
			def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
					AnnotationConfigUtils.class.getClassLoader()));
		} catch (ClassNotFoundException ex) {
			throw new IllegalStateException(
					"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
		}
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
	}

	if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
	}

	return beanDefs;
}
  1. 該方法從傳入的BeanDefinitionRegistry物件,也就是AnnotationConfigApplicationContext物件中獲取到DefaultListableBeanFactory物件。
  2. 為獲取的DefaultListableBeanFactory物件設定屬性
  3. DefaultListableBeanFactory物件中註冊BeanDefinition,註冊的是一些spring內建的PostProcessor的BeanDefinition(關於BeanDefinition的介紹下期在講)。注意,此時只是註冊BeanDefinition,並沒有例項化bean。預設情況下,執行完該方法後,spring容器中所註冊的BeanDefinition為:

((AnnotationConfigApplicationContext) registry).beanFactory.beanDefinitionMap


原始碼學習筆記:https://github.com/shenjianeng/spring-code-study

個人公眾號: