Spring5 源码阅读笔记(1.1.2)delegate.parseCustomElement(ele) 自定义标签的解析和注册

本节会揭晓:
自定义标签解析流程和注册过程
重点:< context:component-scan > 的解析
正是由于对这个自定义标签的解析,Spring 有了@Component,@Lazy,@DependOn,@Primary,@Role,@Description,@PostConstruct,@PreDestroy,@Resource,@Autowired,@Value 的支持

前面的文章 Spring5 源码阅读笔记(1.1)obtainFreshBeanFactory() 末尾介绍到了默认标签解析和自定义标签解析。

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
	if (delegate.isDefaultNamespace(root)) {
		NodeList nl = root.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (node instanceof Element) {
				Element ele = (Element) node;
				if (delegate.isDefaultNamespace(ele)) {

					//默认标签解析
					parseDefaultElement(ele, delegate);
				}
				else {

					//自定义标签解析
					delegate.parseCustomElement(ele);
				}
			}
		}
	}
	else {
		delegate.parseCustomElement(root);
	}
}

默认标签解析已经分析过了,见文章 Spring5 源码阅读笔记(1.1.1)parseDefaultElement(ele, delegate) 默认标签的解析和注册

跟 parseCustomElement :
类 BeanDefinitionParserDelegate
在这里插入图片描述
跟 parseCustomElement :

@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
	String namespaceUri = getNamespaceURI(ele);
	if (namespaceUri == null) {
		return null;
	}
	NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
	if (handler == null) {
		error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
		return null;
	}
	return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}

关于 NamespaceHandler 如果不了解,可以看这篇文章:从源码角度解读 xml 文件中的 xmlns、xsi、xsd

跟 parse :
类 NamespaceHandler
在这里插入图片描述

在这里插入图片描述
跟 parse :
类 BeanDefinitionParser
在这里插入图片描述
我们重点看 ComponentScanBeanDefinitionParser:
这个类对应< context:component-scan > 这个标签

/*
* 1、扫描路径。.class后缀的文件
* 2、要判断类上是否有注解 @Component
* 3、对于有注解的类,创建对应的 BeanDefinition
* 4、完成 BeanDefinition 注册
* 5、完成某些组件的注册
* */
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
	//获取basePackage属性
	String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
	basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
	//可以用逗号分开
	String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
			ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

	//重要程度 2 创建注解扫描器 就是这里面支持了@Component
	// Actually scan for bean definitions and register them. 见1.1.2.1
	ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
	//重要程度 5 扫描并把扫描的类封装成beanDefinition对象并注册 见1.1.2.2
	Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
	//重要程度 5 注册 见1.1.2.3
	registerComponents(parserContext.getReaderContext(), beanDefinitions, element);

	return null;
}
1.1.2.1 configureScanner
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
	//使用默认的过滤器
	boolean useDefaultFilters = true;
	
	if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
		useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
	}

	//创建注解的扫描器
	// Delegate bean definition registration to scanner class.
	ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
	scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
	scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());

	if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
		scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
	}

	try {
		parseBeanNameGenerator(element, scanner);
	}
	catch (Exception ex) {
		parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
	}

	try {
		parseScope(element, scanner);
	}
	catch (Exception ex) {
		parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
	}

	parseTypeFilters(element, scanner, parserContext);

	return scanner;
}

跟 createScanner:

protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
	return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,
			readerContext.getEnvironment(), readerContext.getResourceLoader());
}

跟 ClassPathBeanDefinitionScanner :

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment, @Nullable ResourceLoader resourceLoader) {

	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	this.registry = registry;

	//使用默认的过滤器
	if (useDefaultFilters) {
		//@Component
		registerDefaultFilters();
	}
	setEnvironment(environment);
	setResourceLoader(resourceLoader);
}

跟 registerDefaultFilters :
类 ClassPathScanningCandidateComponentProvider,上面那个类的父类

protected void registerDefaultFilters() {
	//注意这里,说明了要扫描的注解是 Component。具体的说是 includeFilters 里包含了 Component
	this.includeFilters.add(new AnnotationTypeFilter(Component.class));
	ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
	try {
		this.includeFilters.add(new AnnotationTypeFilter(
				((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
		logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
	}
	catch (ClassNotFoundException ex) {
		// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
	}
	try {
		this.includeFilters.add(new AnnotationTypeFilter(
				((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
		logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
	}
	catch (ClassNotFoundException ex) {
		// JSR-330 API not available - simply skip.
	}
}
1.1.2.2 doScan

类 ClassPathBeanDefinitionScanner

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
	Assert.notEmpty(basePackages, "At least one base package must be specified");
	Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
	for (String basePackage : basePackages) {
		//扫描到有注解的类并封装成BeanDefinition对象
		Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
		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);
			}
			if (candidate instanceof AnnotatedBeanDefinition) {
				//支持了@Lazy @DependOn @Primary @Role @Description
				AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
			}
			if (checkCandidate(beanName, candidate)) {
				BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
				//这里不看
				definitionHolder =
						AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
				beanDefinitions.add(definitionHolder);

				//BeanDefinition 注册
				registerBeanDefinition(definitionHolder, this.registry);
			}
		}
	}
	return beanDefinitions;
}

可以看到这里和默认标签的 parseBeanDefinition 有点类似,核心是两步:
一、封装 BeanDefinition 对象
二、对 BeanDefinition 进行注册

第二步和前面默认标签的注册过程是一样的,就不跟代码了。主要看第一步:
跟 findCandidateComponents :
类 ClassPathScanningCandidateComponentProvider
在这里插入图片描述
跟 scanCandidateComponents :

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
	Set<BeanDefinition> candidates = new LinkedHashSet<>();
	try {
		String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
				resolveBasePackage(basePackage) + '/' + this.resourcePattern;

		//这里递归寻找文件
		Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
		boolean traceEnabled = logger.isTraceEnabled();
		boolean debugEnabled = logger.isDebugEnabled();
		for (Resource resource : resources) {
			if (traceEnabled) {
				logger.trace("Scanning " + resource);
			}
			if (resource.isReadable()) {
				try {
					//包装了类的基本信息的对象
					MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
					//如果类上面有候选的注解,这里面可以看一下
					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);
							}
							candidates.add(sbd);
						}
						else {
							if (debugEnabled) {
								logger.debug("Ignored because not a concrete top-level class: " + resource);
							}
						}
					}
					else {
						if (traceEnabled) {
							logger.trace("Ignored because not matching any filter: " + resource);
						}
					}
				}
				catch (Throwable ex) {
					throw new BeanDefinitionStoreException(
							"Failed to read candidate component class: " + resource, ex);
				}
			}
			else {
				if (traceEnabled) {
					logger.trace("Ignored because not readable: " + resource);
				}
			}
		}
	}
	catch (IOException ex) {
		throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
	}
	return candidates;
}

跟 isCandidateComponent :

protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
	for (TypeFilter tf : this.excludeFilters) {
		if (tf.match(metadataReader, getMetadataReaderFactory())) {
			return false;
		}
	}
	//前面出现过的 includeFilters 这里又出现了,这里面就有 Component 注解
	for (TypeFilter tf : this.includeFilters) {
		if (tf.match(metadataReader, getMetadataReaderFactory())) {
			return isConditionMatch(metadataReader);
		}
	}
	return false;
}

看完上面的源码,我们就可以知道了为什么加了 < context:component-scan base-package=""> 标签,spring 就会扫描包下的 @Component 注解。

下面这个方法可以放到后面看,会与1.4.2产生联系。

1.1.2.3 registerComponents
protected void registerComponents(
		XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {

	Object source = readerContext.extractSource(element);
	CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);

	for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
		compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
	}

	// Register annotation config processors, if necessary.
	boolean annotationConfig = true;
	if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
		annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
	}
	if (annotationConfig) {

		//注册了几个比较重要的BeanPostProcessor类
		//ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor
		Set<BeanDefinitionHolder> processorDefinitions =
				AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
		for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
			compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
		}
	}

	readerContext.fireComponentRegistered(compositeDef);
}

跟 registerAnnotationConfigProcessors:
类 org.springframework.context.annotation.AnnotationConfigUtils

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)) {
													//注意这里
		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;
}

跟 registerPostProcessor:

private static BeanDefinitionHolder registerPostProcessor(
		BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

	definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	//这个方法在1.1.1节已经看过了,这里就注册到了beanFactory中,
	//这里并还没有注册到beanPostProcessors里,那一步是在1.3节里
	registry.registerBeanDefinition(beanName, definition);
	return new BeanDefinitionHolder(definition, beanName);
}

再回过头看一下ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor 这三个类实现了什么:
它们都在 org.springframework.context.annotation 包下

ConfigurationClassPostProcessor
在这里插入图片描述
Spring5 源码阅读笔记(2)AnnotationConfigApplicationContext 有更详细的介绍
AutowiredAnnotationBeanPostProcessor
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Spring5 源码阅读笔记(1.4.2.2)applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName) 有更详细的介绍

CommonAnnotationBeanPostProcessor
在这里插入图片描述
注意这个 InstantiationAwareBeanPostProcessor,它会在 1.3 末尾出现,继而与 1.4.2.1 产生联系。

对注解的支持
对 @Autowired @Value 的支持
在这里插入图片描述
对 @PostConstruct,@PreDestroy 的支持
在这里插入图片描述
对 @Resource 的支持见1.4.2.2

Spring5 源码阅读笔记(1.4.2.2)applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName) 有更详细的介绍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值