2.1、spring之注解转换为BeanDefinition

spring支持注解@Component,@Controller,有此类注解的类会自动注册为一个bean,所有bean在生成之前都由一个BeanDefinition解析而来。
假设如果我们自己来写处理注解的过程
(1)读取项目中的所有类,判断类是否包含指定的注解。
(2)如果包含对应的注解,根据注解生成对应的BeanDefinition。
(3)将生成的BeanDefinition存储起来

spring 也是按照我们上面的操作来进行。
2.1、spring之注解转换为BeanDefinition
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 类继承关系

2.1、spring之注解转换为BeanDefinition

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
是上方的一个实现类。主要是判断类的名字是否满足给定的调校