2.1、spring之註解轉換爲BeanDefinition

spring支持註解@Component,@Controller,有此類註解的類會自動註冊爲一個bean,所有bean在生成之前都由一個BeanDefinition解析而來。
假設如果我們自己來寫處理註解的過程
(1)讀取項目中的所有類,判斷類是否包含指定的註解。
(2)如果包含對應的註解,根據註解生成對應的BeanDefinition。
(3)將生成的BeanDefinition存儲起來

spring 也是按照我們上面的操作來進行。
在這裏插入圖片描述
spring中存在ClassPathBeanDefinitionScanner類和ClassPathScanningCandidateComponentProvider,用來搜索包含指定註解的類,並生成對應的BeanDefinition(ScannedGenericBeanDefinition)或者生成BeanDefinitionHolder

一、掃描並解析

spring 將 這一操作放在ClassPathScanningCandidateComponentProvider
findCandidateComponents方法中

public Set<BeanDefinition> findCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>();
		try {
		   // 1、獲取對應路徑下的所有類
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
			Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
		
			for (Resource resource : resources) {
				if (resource.isReadable()) {
					try {
						MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
						 // 2、判斷是否包含指定的註解或者其他的條件
						if (isCandidateComponent(metadataReader)) {
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setResource(resource);
							sbd.setSource(resource);
							if (isCandidateComponent(sbd)) {
								candidates.add(sbd);
							}
					.....
		return candidates;
	}

2.1 獲取所有的文件

可以參考 https://blog.csdn.net/liu20111590/article/details/89180320

2.2 判斷條件

protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
		for (TypeFilter tf : this.excludeFilters) {
			if (tf.match(metadataReader, this.metadataReaderFactory)) {
				return false;
			}
		}
		for (TypeFilter tf : this.includeFilters) {
			if (tf.match(metadataReader, this.metadataReaderFactory)) {
				return isConditionMatch(metadataReader);
			}
		}
		return false;
	}

從上面可以看到,對於條件的判斷是採用的TypeFilter來進行的。接下來我們可以來詳細瞭解一下TypeFilter

二、存儲BeanDefinition

spring 自行實現了一部分,當然我們可以不使用spring實現,自行實現也可以。
ClassPathBeanDefinitionScannerdoScan方法中

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
		for (String basePackage : basePackages) {
		    // 1、獲取符合條件的類並生成對應的BeanDefinition
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			for (BeanDefinition candidate : candidates) {
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				// 2、生成bean的名稱
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				// 3、判斷是否生成過了,如果沒有重新存儲
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}

三、TypeFilter詳解

3.1 TypeFilter接口和繼承關係圖

3.1.1 接口信息

TypeFilter接口

boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException;

我們看到其中只有一個方法,既match方法,符合規則返回true,不符合返回false。
我們可以看一下入參:、
MetadataReader接口:

    //所在的Resource
	Resource getResource();
	// 類的元素信息
	ClassMetadata getClassMetadata();
	// 類中的所有註解,包含方法上的註解
	AnnotationMetadata getAnnotationMetadata();

從這裏,我們可以獲取到當前類的所有信息

3.1.2 類繼承關係

在這裏插入圖片描述

3.2 常用的TypeFilter

3.2.1 具有繼承關係的處理

AbstractTypeHierarchyTraversingFilter:
用來處理那些存在繼承關係的接口和類,根據配置,會掃描所有的父類和所有實現的接口。此類是抽象類,如果有具體的實現類不滿足要求,可以自行繼承實現。

我們可以看兩個具體的實現類。
AnnotationTypeFilter
用來處理包含指定註解的類
AssignableTypeFilter
用來處理是否是指定類型

3.2.2 Aspectj支持

AspectJTypeFilter用來處理對AspectJ類型的支持

3.2.3 單獨對類的處理

AbstractClassTestingTypeFilter是一個單獨對類信息的抽象類。我們可以看一下如下的代碼。指定了抽象方法,只處理類信息相關。

  @Override
	public final boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {

		return match(metadataReader.getClassMetadata());
	}
	protected abstract boolean match(ClassMetadata metadata);

RegexPatternTypeFilter
是上方的一個實現類。主要是判斷類的名字是否滿足給定的調校

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