同步操作将从 xuchengsheng/spring-reading 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
✒️ 作者 - Lex 📝 博客 - 掘金 📚 源码地址 - github
Resource接口
Resource
接口来获取资源的输入流、文件路径等信息。AnnotationMetadata接口
MetadataReader接口
MetadataReader
通常用于扫描包中的类,并从这些类中提取注解信息,以便配置 Spring Bean。路径和模式解析
classpath*:com/xcs/spring/**/*.xml
。TypeFilter
是 Spring 框架中的一个接口,用于在组件扫描期间对类进行筛选。通过实现 match
方法,我们可以定义自己的逻辑,决定哪些类应该被包含在组件扫描的结果中,而哪些类应该被排除。这一灵活的机制在spring中的 @ComponentScan
注解时被使用,可以通过自定义的 TypeFilter
对类进行精确的过滤,满足复杂应用程序结构或特定条件下的组件管理需求。Spring 提供了多个内置的 TypeFilter
实现,如 AnnotationTypeFilter
和 AssignableTypeFilter
,用于基于注解或类型进行筛选。
自定义过滤逻辑
TypeFilter
接口,通过覆盖 match
方法定义自己的过滤逻辑。这使得可以根据特定的条件,如类的注解、实现的接口或继承关系等,来决定类是否应该被包含在组件扫描的结果中。组件扫描定制
@ComponentScan
注解配置类时,可以通过设置 includeFilters
和 excludeFilters
属性,传入自定义的 TypeFilter
实例,从而定制组件扫描的规则。这样可以更精确地控制哪些类应该被纳入 Spring 容器的管理,哪些类应该被排除。适应复杂应用结构
TypeFilter
,可以根据项目的实际结构,有选择地将类包含或排除。灵活性和可扩展性
TypeFilter
提供了一种灵活的机制,使得我们可以根据特定需求扩展和定制组件扫描的行为。这种灵活性对于需要动态适应不同场景的应用程序是非常有用的。TypeFilter
接口,作为组件扫描过程中自定义类过滤器的基础。该接口包含一个match
方法,通过传入MetadataReader
和MetadataReaderFactory
,我们可以实现自定义的过滤逻辑,决定哪些类应该被包含在组件扫描结果中,从而增强了Spring框架在应用初始化时对类的筛选和管理的灵活性。
/**
* 使用 org.springframework.core.type.classreading.MetadataReader 的类型过滤器的基础接口。
*
* @author Costin Leau
* @author Juergen Hoeller
* @author Mark Fisher
* @since 2.5
*/
@FunctionalInterface
public interface TypeFilter {
/**
* 确定该过滤器是否与给定元数据描述的类匹配。
*
* @param metadataReader 目标类的元数据读取器
* @param metadataReaderFactory 用于获取其他类的元数据读取器的工厂(例如超类和接口)
* @return 是否匹配该过滤器
* @throws IOException 在读取元数据时发生 I/O 失败时抛出异常
*/
boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException;
}
AnnotationTypeFilter(基于注解的过滤器)
AssignableTypeFilter(基于类型的过滤器):
AspectJTypeFilter(基于AspectJ表达式的过滤器):
RegexPatternTypeFilter(基于正则表达式的过滤器):
使用 Spring 框架的 TypeFilter
进行类的筛选过程。通过创建路径匹配的资源模式解析器和元数据读取器工厂,以及定义一个注解类型过滤器(我们最佳实践中为 MyAnnotation
),然后从classpath*:com/xcs/spring/**/*.class
路径下获取所有类文件,并筛选出带有指定注解的类。遍历扫描到的类文件,输出文件名以及注解类型过滤的结果。
public class TypeFilterDemo {
public static void main(String[] args) throws IOException {
// 创建路径匹配的资源模式解析器
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// 创建一个简单的元数据读取器工厂
SimpleMetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
// 创建一个注解类型过滤器,用于匹配带有 MyAnnotation 注解的类
TypeFilter annotationTypeFilter = new AnnotationTypeFilter(MyAnnotation.class);
// 使用资源模式解析器获取所有匹配指定路径的类文件
Resource[] resources = resolver.getResources("classpath*:com/xcs/spring/**/*.class");
// 遍历扫描到的类文件
for (Resource resource : resources) {
// 获取元数据读取器
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
// 使用注解类型过滤器匹配当前类
boolean match = annotationTypeFilter.match(metadataReader, metadataReaderFactory);
// 输出扫描到的文件名和匹配结果
System.out.printf("扫描到的文件: %-20s || 筛选器是否匹配: %s%n", resource.getFile().getName(), match);
}
}
}
MyAnnotation
注解被用作 TypeFilter
中的匹配条件,用于过滤带有此注解的类。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {
}
定义了一个名为 MyComponent
的类,并使用了 MyAnnotation
注解。
package com.xcs.spring.component;
@MyAnnotation
public class MyComponent {
}
定义了一个名为 MyController
的类,但是该类没有使用任何自定义注解。
package com.xcs.spring.controller;
public class MyController {
}
定义了一个名为 MyRepository
的类,但是该类没有使用任何自定义注解。
package com.xcs.spring.repository;
public class MyRepository {
}
定义了一个名为 MyService
的类,但是该类没有使用任何自定义注解。
package com.xcs.spring.service;
public class MyService {
}
运行结果发现,可以看出 MyController
、MyRepository
、MyService
并没有匹配到注解类型过滤器,而带有 MyAnnotation
注解的类 MyComponent
成功匹配。这符合预期,证明了注解类型过滤器在筛选类时的有效性。
扫描到的文件: TypeFilterDemo.class || 筛选器是否匹配: false
扫描到的文件: MyAnnotation.class || 筛选器是否匹配: false
扫描到的文件: MyComponent.class || 筛选器是否匹配: true
扫描到的文件: MyController.class || 筛选器是否匹配: false
扫描到的文件: MyRepository.class || 筛选器是否匹配: false
扫描到的文件: MyService.class || 筛选器是否匹配: false
ClassPathScanningCandidateComponentProvider
registerDefaultFilters
方法是 ClassPathScanningCandidateComponentProvider
类的一个方法,用于注册默认的类型过滤器。这个方法在组件扫描时被调用,它会添加一些默认的过滤器到 includeFilters
集合中,这些过滤器包括,用于扫描带有 @Component
注解的类,以及JSR 规范中的一些注解类型过滤器,如 ManagedBean
和 Named
注解。ComponentScanAnnotationParser
typeFiltersFor
方法是 ComponentScanAnnotationParser
类的一个私有方法,用于根据 @ComponentScan
注解中的属性信息创建类型过滤器列表。根据不同的过滤器类型(如注解类型、可分配类型、自定义类型等),它会创建对应的 TypeFilter
实例并添加到列表中。ComponentScanBeanDefinitionParser
createTypeFilter
方法属于 ComponentScanBeanDefinitionParser
类,用于在解析 <component-scan>
元素时根据 XML 配置信息创建类型过滤器。它根据配置中的 filter-type
属性和 filter-expression
属性,动态选择创建相应的类型过滤器。支持的过滤器类型包括注解类型、可分配类型、AspectJ 表达式、正则表达式等。无法正确匹配类
自定义的 TypeFilter 不生效
TypeFilter
实现正确并且被正确地配置。检查实现中的匹配逻辑是否符合预期。包扫描结果为空
多个 TypeFilter 失效
TypeFilter
的使用场景和条件不重叠,否则可能会出现只有一个过滤器生效的情况。AspectJ 表达式匹配失败:
AspectJTypeFilter
的构造函数中的类加载器是否正确。性能问题:
TypeFilter
导致性能问题。考虑优化过滤器的实现,或者在适当的情况下缓存扫描结果。可以使用缓存或其他优化技术来减轻性能问题。此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。