曹工说Spring Boot源码(12)-- Spring解析xml文件,到底从中得到了什么(context:component-scan完整解析) (3)

解析自定义的filter

protected void parseTypeFilters( Element element, ClassPathBeanDefinitionScanner scanner, XmlReaderContext readerContext, ParserContext parserContext) { // Parse exclude and include filter elements. ClassLoader classLoader = scanner.getResourceLoader().getClassLoader(); // 因为include-filter和exclude-filter是以子元素方式配置的,不是属性来配置的;所以获取子节点并便利 NodeList nodeList = element.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { String localName = parserContext.getDelegate().getLocalName(node); // 如果是include类型... if (INCLUDE_FILTER_ELEMENT.equals(localName)) { // 创建typefilter TypeFilter typeFilter = createTypeFilter((Element) node, classLoader); scanner.addIncludeFilter(typeFilter); } else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) { TypeFilter typeFilter = createTypeFilter((Element) node, classLoader); scanner.addExcludeFilter(typeFilter); } } } } } @SuppressWarnings("unchecked") protected TypeFilter createTypeFilter(Element element, ClassLoader classLoader) { String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE); String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE); // filter 一共5种类型,所以下面在各种if判断 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); } else { throw new IllegalArgumentException("Unsupported filter type: " + filterType); } }

表格总结一下,就是:

filter-type 对应类型的class 说明 我的理解
annotation   AnnotationTypeFilter   "annotation" indicates an annotation to be present at the type level in target components;   匹配指定类型的注解  
assignable   AssignableTypeFilter   "assignable" indicates a class (or interface) that the target components are assignable to (extend/implement);   判断一个class是不是这里指定的类型或其子类  
aspectj   AspectJTypeFilter   "aspectj" indicates an AspectJ type expression to be matched by the target components;   需要满足aspectj表达式,类似于指定切点那种  
regex   RegexPatternTypeFilter   "regex" indicates a regex expression to be matched by the target components' class names;   需要满足正则表达式  
custom   由xml元素里指定类型   "custom" indicates a custom implementation of the org.springframework.core.type.TypeFilter interface.   自定义实现TypeFilter接口  

这里的typefilter接口,接口如下,主要就是,传给你一个class的元数据,你判断是否留下,留下就返回true:

public interface TypeFilter { /** * Determine whether this filter matches for the class described by * the given metadata. * @param metadataReader the metadata reader for the target class * @param metadataReaderFactory a factory for obtaining metadata readers * for other classes (such as superclasses and interfaces) * @return whether this filter matches * @throws IOException in case of I/O failure when reading metadata */ boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException; }

有如下实现(图小,可单独tab查看):

曹工说Spring Boot源码(12)-- Spring解析xml文件,到底从中得到了什么(context:component-scan完整解析)

doScan-具体扫描beanDefinition执行者

如果大家有点忘了,可以回到最前面看下之前的图,这是主线的最后一个环节。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsjxd.html