【springboot源碼分析】2.加載sources類BeanDefinition


在上一篇【springboot源碼分析】SpringApplication實例化main函數裏面有這麼一行代碼

 SpringApplication.run(RpcClientApplication.class, args)

這篇文章的主角sources就是RpcClientApplication.class,之所以是sources是因爲,springboot可以多個sources一起啓動,也就是run還有一個重載方法可以傳一個sources數組。


springboot對類注入以及自動裝配源頭就是解析sources,要想解析sources第一步,無可厚非的需要sources加載得到其BeanDefinition。

prepareContext(context, environment, listeners, applicationArguments,printedBanner);

上面一行代碼是加載sources的BeanDefinition的入口


prepareContext方法體爲

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

load(context, sources.toArray(new Object[0]))就是要加載sources的BeanDefinition。


跟蹤進入AnnotatedBeanDefinitionReader.doRegisterBean(…)的方法體

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

	AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
	if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
		return;
	}

	abd.setInstanceSupplier(instanceSupplier);
	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));
			}
		}
	}
	for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
		customizer.customize(abd);
	}

	BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
	definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
	BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

這裏需要注意的是sources的BeanDefinition實際類型是AnnotatedGenericBeanDefinition,在之後對sources進行解析的時候很重要的。執行完doRegisterBean之後,就可以在DefaultListableBeanFactory中看到sources的BeanDefinition信息。

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