spring源碼分析| 第一篇:內置後置處理器及自定義配置註冊解析

1. 註冊過程解析(語言層面)

  • 解析說明

    由於spring代碼加載過程非常複雜,在此先通過語言描述大體介紹對象註冊進spring容器的過程,下面會通過解析spring中重點源碼來分析每一步驟

  • 創建spring容器: new AnnotationConfigApplicationContext()

    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    	this();
    	register(componentClasses);
    	refresh();
    }
    
  • 執行AnnotationConfigApplicationContext父類構造方法,即創建bean工廠:new DefaultListableBeanFactory()

  • 執行構造方法中this()方法:主要創建了AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScanner兩個類

    1.AnnotatedBeanDefinitionReader: 執行構造方法,完成後置處理器的創建,轉爲beanDefinition,重點關注ConfigurationClassPostProcessor
    2.ClassPathBeanDefinitionScanner: 掃描類路徑下bean,並將其變爲beanDefinition交註冊進spring容器

  • 執行構造方法中register(componentClasses)方法: 完成後置處理器(spring創建,自定義)的創建,傳入配置類轉換爲beanDefinition並註冊至spring容器

  • 執行構造方法中refresh()方法: 解析配置類,將所有自定義對象掃描、解析並轉換爲beanDefinition,最終註冊至spring容器

2. 註冊過程解析(代碼層面)

2.1 構造方法解析

AnnotationConfigApplicationContext acc = new AnnotationConfigApplicationContext(AppConfig.class);

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();
		register(componentClasses);
		refresh();
	}

構造方法中包含以下三部份:
1. this(): 創建spring的bean工廠(DefaultListableBeanFactory)
2. register(): 創建spring所需後置處理器(beanPostProcessor,beanFactoryPostProcessor),同時將創建的後置處理器、自定義配置類註冊進spring容器
3. refresh(): 解析註冊進spring容器的配置類,根據配置的componScan地址解析基礎包下自定義bean,並將解析的bean註冊進spring容器

2.2 this()方法解析

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;

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

解析方法:
1.AnnotationConfigApplicationContext繼承至GenericApplicationContext,則執行父類構造方法,創建bean工廠(DefaultListableBeanFactory)

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

private final DefaultListableBeanFactory beanFactory;

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

2.執行AnnotatedBeanDefinitionReader()構造方法,調用registerAnnotationConfigProcessors方法,創建spring內置beanPostProcessor和BeanFactoryPostProcessor

 public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
		BeanDefinitionRegistry registry, @Nullable Object source) {
	// 獲取beanFactory
	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);
	// 註冊spring內置五個後置處理器
	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));
	}

	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.創建spring內置處理器,其中重點關注ConfigurationClassPostProcessor,該後置處理器用於處理添加了@Configuration註解配置類
2.執行registerPostProcessor()將創建的內置處理器註冊至spring容器中
3.ConfigurationClassPostProcessor繼承至beanFactoryPostProcessor,其餘4個後置處理器實現beanPOstProcessor,後續會介紹兩者差異

在這裏插入圖片描述
執行結果::
在這裏插入圖片描述
3.ClassPathBeanDefinitionScanner:掃描bean,並將其轉爲beanDefinition同時註冊至spring容器中,我們用不了,在此就不做解析

2.3 register()方法解析

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
		@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
		@Nullable BeanDefinitionCustomizer[] customizers) {

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

	abd.setInstanceSupplier(supplier);
	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));
			}
		}
	}
	if (customizers != null) {
		for (BeanDefinitionCustomizer customizer : customizers) {
			customizer.customize(abd);
		}
	}

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

1.創建AnnotatedGenericBeanDefinition,所有註解類均使用該beanDefinition
2.設置註解BeanDefinition元數據和通用註解黙認值,包含scope,lazy,Description
3.將beanDefinition包裝成BeanDefinitionHolder,無實際意義,便於傳參
4.執行BeanDefinitionReaderUtils.registerBeanDefinition()將傳入配置類註冊至spring容器

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 existingDefinition = this.beanDefinitionMap.get(beanName);
	if (existingDefinition != null) {
		if (!isAllowBeanDefinitionOverriding()) {
			throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
		}
		else if (existingDefinition.getRole() < beanDefinition.getRole()) {
			// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
			if (logger.isInfoEnabled()) {
				logger.info("Overriding user-defined bean definition for bean '" + beanName +
						"' with a framework-generated bean definition: replacing [" +
						existingDefinition + "] with [" + beanDefinition + "]");
			}
		}
		else if (!beanDefinition.equals(existingDefinition)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Overriding bean definition for bean '" + beanName +
						"' with a different definition: replacing [" + existingDefinition +
						"] with [" + beanDefinition + "]");
			}
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("Overriding bean definition for bean '" + beanName +
						"' with an equivalent definition: replacing [" + existingDefinition +
						"] 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<>(this.beanDefinitionNames.size() + 1);
				updatedDefinitions.addAll(this.beanDefinitionNames);
				updatedDefinitions.add(beanName);
				this.beanDefinitionNames = updatedDefinitions;
				removeManualSingletonName(beanName);
			}
		}
		else {
			// Still in startup registration phase
			this.beanDefinitionMap.put(beanName, beanDefinition);
			this.beanDefinitionNames.add(beanName);
			removeManualSingletonName(beanName);
		}
		this.frozenBeanDefinitionNames = null;
	}

	if (existingDefinition != null || containsSingleton(beanName)) {
		resetBeanDefinition(beanName);
	}
}

配置類註冊進spring容器過程如下圖:
實際將上述處理的beanDefinition保存至beanFactory(DefaultListableBeanFactory)中的beanDefinitionMap中,完成此步操作後,beanFacroy的beanDefinitionMap中包含6個對象,即上述創建的6個後置處理器和自定義傳入的配置類,如下圖
執行結果如下,從下圖可看出執行完register()方法後,beanDefinitionMap中增加了appConfig的映射
在這裏插入圖片描述

2.4 refresh()方法解析

refresh()主要解析自定義後置處理器、自定義對象註冊至spring容器,涉及動西較多,詳情見文章spring源碼分析| 第二篇:自定義後置處理器及自定義對象註冊解析

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