Spring5源碼解析1-從啓動容器開始

從啓動容器開始

最簡單的啓動spring的代碼以下:java

@Configuration
@ComponentScan
public class AppConfig {
}

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

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

AnnotationConfigApplicationContext

點開AnnotationConfigApplicationContext(AppConfig.class);方法查看源碼:github

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 類。spring

有參構造器調用了無參構造器,點開源碼:學習

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的默認實現。this

public GenericApplicationContext() {
	this.beanFactory = new DefaultListableBeanFactory();
}
複製代碼

DefaultListableBeanFactory

AnnotationConfigApplicationContext的構造器中還建立了兩個對象:AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScannerlua

先說scanner的做用,經過查看源碼能夠發現,這個scanner只有在手動調用AnnotationConfigApplicationContext的一些方法的時候纔會被使用(經過後面的源碼探究也能夠發現,spring並非使用這個scanner來掃描包獲取Bean的)。spa

scanner

建立AnnotatedBeanDefinitionReader對象。spring在建立reader的時候把this當作了參數傳給了構造器。也就是說,reader對象裏面包含了一個this對象,也就是AnnotationConfigApplicationContext對象。AnnotationConfigApplicationContext 實現了BeanDefinitionRegistry接口。點開this.reader = new AnnotatedBeanDefinitionReader(this);源碼:code

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
	this(registry, getOrCreateEnvironment(registry));
}
複製代碼

從傳入的BeanDefinitionRegistry對象,也就是AnnotationConfigApplicationContext對象中獲取Environment(共用同一個Environment),而後又接着調用另外一個構造器。點開源碼:cdn

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.png


源碼學習筆記:github.com/shenjianeng…

相關文章
相關標籤/搜索