spring源码的xml解析过程-2(注册注解处理器)


接上一篇xml解析,回到
org.springframework.beans.factory.xml.NamespaceHandlerSupport#parse

@Override
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		return findParserForElement(element, parserContext)
		.parse(element, parserContext);
	}
ComponentScanBeanDefinitionParser 标签解析器

component-scan标签解析类

<!-- 激活Spring注解方式:自动扫描,并注入bean -->
<context:component-scan base-package="com.consult.action" 
	use-default-filters="" 
	annotation-config="">
		<context:include-filter type="annotation"
		expression="org.springframework.stereotype.Controller" />
		<context:exclude-filter type="annotation"
		expression="org.springframework.stereotype.Service" />
</context:component-scan>
  • Annotation org.example.SomeAnnotation符合SomeAnnoation的target class
  • Assignable org.example.SomeClass指定class或interface的全名
  • Aspectj org.example…*Service+AspectJ語法
  • Regex org.example.Default.* Regelar Expression
  • Custom org.example.MyTypeFilterSpring3新增自定义Type,见org.springframework.core.type.TypeFilter

在解析类里面完成了
1.基本包的扫描
2.类型过滤器的配置
3.<context:annotation-config/>配置的兼容
4.注解处理器BeanPostProcessor的注册

org.springframework.context.annotation.ComponentScanBeanDefinitionParser#parse

// base-package 标签属性值,即扫描的包配置
String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);

ClassPathBeanDefinitionScanner scanner = 
configureScanner(parserContext, element);

org.springframework.context.annotation.ComponentScanBeanDefinitionParser#configureScanner

//默认过滤器标记
boolean useDefaultFilters = true;

ClassPathBeanDefinitionScanner scanner = 
createScanner(parserContext.getReaderContext(), useDefaultFilters);

org.springframework.context.annotation.ComponentScanBeanDefinitionParser#createScanner

return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), 
useDefaultFilters,
readerContext.getEnvironment(), 
readerContext.getResourceLoader());

org.springframework.context.annotation.ClassPathBeanDefinitionScanner#ClassPathBeanDefinitionScanner(org.springframework.beans.factory.support.BeanDefinitionRegistry, boolean, org.springframework.core.env.Environment, org.springframework.core.io.ResourceLoader)

//注册默认的过滤器
if (useDefaultFilters) {
	registerDefaultFilters();
}

org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#registerDefaultFilters

// 扫描 @Component 注解以及  @Component注解的子类,如@Service
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
// 扫描 @ManagedBean 注解 JSR-250
this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) 
ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));

// 扫描 @Named 注解 JSR-330
this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));

见 AnnotationTypeFilter 类中的 annotationType 字段,注解类型

返回到
org.springframework.context.annotation.ComponentScanBeanDefinitionParser#configureScanner

parseTypeFilters(element, scanner, parserContext);

org.springframework.context.annotation.ComponentScanBeanDefinitionParser#parseTypeFilters

   //include-filter 元素解析
	if (INCLUDE_FILTER_ELEMENT.equals(localName)) {
		TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
			scanner.addIncludeFilter(typeFilter);
		}
	//exclude-filter 元素解析	
	else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) {
			TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
			scanner.addExcludeFilter(typeFilter);
	}

org.springframework.context.annotation.ComponentScanBeanDefinitionParser#createTypeFilter

// annotation 过滤是最常用的
if ("annotation".equals(filterType)) {
				return new AnnotationTypeFilter((Class<Annotation>) classLoader.loadClass(expression));
			}
			else if ("assignable".equals(filterType)) {
				return new AssignableTypeFilter(classLoader.loadClass(expression));
			}
			else if ("aspectj".equals(filterType)) {
				return new AspectJTypeFilter(expression, classLoader);
			}
			else if ("regex".equals(filterType)) {
				return new RegexPatternTypeFilter(Pattern.compile(expression));
			}
			else if ("custom".equals(filterType)) {
				Class<?> filterClass = classLoader.loadClass(expression);
				if (!TypeFilter.class.isAssignableFrom(filterClass)) {
					throw new IllegalArgumentException(
							"Class is not assignable to [" + TypeFilter.class.getName() + "]: " + expression);
				}
				return (TypeFilter) BeanUtils.instantiateClass(filterClass);
			}

返回到
org.springframework.context.annotation.ComponentScanBeanDefinitionParser#parse

Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);

org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan

Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#findCandidateComponents

// 将配置包路径的 点 转为 斜杠
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// 加载包下的 class 文件
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);					

org.springframework.context.support.AbstractApplicationContext#getResources

return this.resourcePatternResolver.getResources(locationPattern);

org.springframework.core.io.support.PathMatchingResourcePatternResolver#getResources

// 如果是 classpath*: 前缀时
	if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
			// a class path resource (multiple resources for same name possible)
			if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
				// a class path resource pattern
				// 查看该方法
				return findPathMatchingResources(locationPattern);
			}
			else {
				// all class path resources with the given name
				return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
			}
		}

org.springframework.core.io.support.PathMatchingResourcePatternResolver#findPathMatchingResources


if (rootDirURL.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
				result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirURL, subPattern, getPathMatcher()));
			}
			// 识别 jar 包
			else if (ResourceUtils.isJarURL(rootDirURL) || isJarResource(rootDirResource)) {
				result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirURL, subPattern));
			}
			else {
				
// class 文件添加到结集中,查看 	doFindPathMatchingFileResources			result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
			}

org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindPathMatchingFileResources

rootDir = rootDirResource.getFile().getAbsoluteFile();

return doFindMatchingFileSystemResources(rootDir, subPattern);

org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindMatchingFileSystemResources

Set<File> matchingFiles = retrieveMatchingFiles(rootDir, subPattern);

org.springframework.core.io.support.PathMatchingResourcePatternResolver#retrieveMatchingFiles


String fullPattern = StringUtils.replace(rootDir.getAbsolutePath(), File.separator, "/");

doRetrieveMatchingFiles(fullPattern, rootDir, result);

org.springframework.core.io.support.PathMatchingResourcePatternResolver#doRetrieveMatchingFiles

File[] dirContents = dir.listFiles();

for (File content : dirContents) {
			String currPath = StringUtils.replace(content.getAbsolutePath(), File.separator, "/");
			if (content.isDirectory() && getPathMatcher().matchStart(fullPattern, currPath + "/")) {
				if (!content.canRead()) {
					if (logger.isDebugEnabled()) {
						logger.debug("Skipping subdirectory [" + dir.getAbsolutePath() +
								"] because the application is not allowed to read the directory");
					}
				}
				else {
				    // 作递归查找文件
					doRetrieveMatchingFiles(fullPattern, content, result);
				}
			}
			if (getPathMatcher().match(fullPattern, currPath)) {
			    // 是文件是加入到集合中
				result.add(content);
			}
		}

返回到
org.springframework.core.io.support.PathMatchingResourcePatternResolver#doFindMatchingFileSystemResources

// matchingFiles 所有class 文件
Set<File> matchingFiles = retrieveMatchingFiles(rootDir, subPattern);
Set<Resource> result = new LinkedHashSet<Resource>(matchingFiles.size());
for (File file : matchingFiles) {
    // class 文件转为 Resource后,添加到集合中
	result.add(new FileSystemResource(file));
}

返回到
org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#findCandidateComponents

// 获取所有 class 文件转为 Resource对象,见上
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);

// 获取class文件中所有的注解信息,封装到 MetadataReader 对象中
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);

// isCandidateComponent 过滤class文件上的所有的注解,即判断类上是否有 @Component、@Service、@Controller 等注解
if (isCandidateComponent(metadataReader)) {
	ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
	sbd.setResource(resource);
	sbd.setSource(resource);
	if (isCandidateComponent(sbd)) {
		if (debugEnabled) {
			logger.debug("Identified candidate component class: " + resource);
								}
					// 将注解的 BeanDefinition 对象添加到集合中			
					candidates.add(sbd);
							}
							else {
								if (debugEnabled) {
									logger.debug("Ignored because not a concrete top-level class: " + resource);
								}
							}
						}

MetadataReader 类中有 AnnotationMetadata getAnnotationMetadata(); 方法,可以获取类中的所有注解
isCandidateComponent 方法过滤所有的注解,即判断类上是否有 @Component、@Service、@Controller 等注解,如果有则创建一个 ScannedGenericBeanDefinition ,将注解信息封装成 BeanDefinition 对象中

返回到
org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan

for (String basePackage : basePackages) {
            // 返回每个类中的注解封装的BeanDefinition 对象集合
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			// 循环 BeanDefinition 
			for (BeanDefinition candidate : candidates) {
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				// 是 AnnotatedBeanDefinition 类型时
				if (candidate instanceof AnnotatedBeanDefinition) {
// 解析注解的相关属性值					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}

org.springframework.context.annotation.AnnotationConfigUtils#processCommonDefinitionAnnotations(org.springframework.beans.factory.annotation.AnnotatedBeanDefinition)

processCommonDefinitionAnnotations(abd, abd.getMetadata());

org.springframework.context.annotation.AnnotationConfigUtils#processCommonDefinitionAnnotations(org.springframework.beans.factory.annotation.AnnotatedBeanDefinition, org.springframework.core.type.AnnotatedTypeMetadata)

if (metadata.isAnnotated(Lazy.class.getName())) {
			abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value"));
		}
		else if (abd.getMetadata() != metadata && abd.getMetadata().isAnnotated(Lazy.class.getName())) {
			abd.setLazyInit(attributesFor(abd.getMetadata(), Lazy.class).getBoolean("value"));
		}

		if (metadata.isAnnotated(Primary.class.getName())) {
			abd.setPrimary(true);
		}

返回到
org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan

if (checkCandidate(beanName, candidate)) {
// BeanDefinition 封装成 BeanDefinitionHolder 
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
		definitionHolder =
		AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		beanDefinitions.add(definitionHolder);
		// 注册 BeanDefinition
		registerBeanDefinition(definitionHolder, this.registry);
}

org.springframework.context.annotation.ClassPathBeanDefinitionScanner#registerBeanDefinition

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);

org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition

registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition

this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;

// ....
//缓存 beanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
// beanDefinitionNames 集合中添加 beanName
this.beanDefinitionNames.add(beanName);

注解的 beanDefinition 注册完毕,注册 beanDefinition 其实就是将 beanDefinition 对象缓存在 DefaultListableBeanFactory 类中的 一些集合中

返回到
org.springframework.context.annotation.ComponentScanBeanDefinitionParser#parse

// 注解的 beanDefinition 集合
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);

org.springframework.context.annotation.ComponentScanBeanDefinitionParser#registerComponents

// 兼容 annotation-config 标签配置 
boolean annotationConfig = true;
if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
	annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
}
  // 
	if (annotationConfig) {
		Set<BeanDefinitionHolder> processorDefinitions =
		// 注册相关注解的支持处理类,如 @Autowired、@Required 、@Configuration 等注解
		AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
		for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
			compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
			}
		}

org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)

// @Order 注解的支持
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);

// @Lazy 注解的支持
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());

// @Configuration 注解的支持
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);

// @Autowired 注解的支持
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
// 注册 PostProcessor 处理器,查看该方法
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));

// @Required 注解的支持
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);

// @Resource 注解的支持 JSR-250
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);

// JPA 注解的支持
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
	AnnotationConfigUtils.class.getClassLoader()));
	
// @EventListener 注解的支持
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);

org.springframework.context.annotation.AnnotationConfigUtils#registerPostProcessor

// 这里是对注解 @Autowired 的 BeanDefinition 对象(上面的那个)进行注册
registry.registerBeanDefinition(beanName, definition);
// 返回 BeanDefinitionHolder
return new BeanDefinitionHolder(definition, beanName);

对 BeanDefinition 对象注册时都会进入到 org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition 方法中

返回到
org.springframework.context.annotation.ComponentScanBeanDefinitionParser#parse

总结:<context:component-scan base-package="com.dn.spring.controller" > 标签在扫描配置的包时,会注册很多关于注解的相关处理器

<context:annotation-config/> 的处理器 org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser 里面其实注册了很多关于注解的处理器

总结
  1. 通过扫描指定包路径并加载 class 文件,将 class 文件转为 Resource对象
  2. 注册要扫描class文件中的注解,例如: @Component 注解 以及 @Component注解的子类,如@Service 等
  3. 过滤class文件上的所有的注解,即判断类上是否有 @Component、@Service、@Controller 等注解,将符合的 resource 封装为 ScannedGenericBeanDefinition 对象即 BeanDefinition
  4. 将 BeanDefinition 封装成 BeanDefinitionHolder 并进行注册,注册 beanDefinition 其实就是将 beanDefinition 对象缓存在 DefaultListableBeanFactory 类中的 一些集合中
  5. 注册相关注解的处理器类即BeanPostProcessor或BeanFactoryPostProcessor的子类,如 @Autowired、@Required 、@Configuration 等注解的解析和处理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值