02、Spring常用注解一@ComponentScan
1. @ComponentScan 扫描规则
1.1 指定要扫描的包
- 1 新建配置类Cap2MainConfig,
@ComponentScan(value = "com.zz.cap2")
public class Cap2MainConfig {
}
@ComponentScan(value = “com.zz.cap2”)表示扫描此目录下的包。
- 2 在com.zz.cap2目录下新建要扫描的类
OrderController
@Controller
public class OrderController {
}
OrderService
@Service
public class OrderService {
}
OrderDao
@Repository
public class OrderDao {
}
- 3 新建测试类Cap2Test
public class Cap2Test {
@Test
public void test1() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Cap2MainConfig.class);
//从容器获取bean定义的名称
String[] names = context.getBeanDefinitionNames();
for( String name : names) {
System.out.println(name);
}
}
}
结果:
使用 ApplicationContext 的 getBeanDefinitionNames() 方法获取已经注册到容器中的 bean 的名称。
1.2 定制包扫描的过滤规则
1.2.1 excludeFilters 和 includeFilters 的使用
1.使用 excludeFilters 来按照规则排除某些包的扫描
修改配置类:
@ComponentScan(value = "com.zz.cap2", excludeFilters = {@Filter(type = FilterType.ANNOTATION, value = Controller.class)})
public class Cap2MainConfig {
}
excludeFilters 的参数是一个 Filter[] 数组,然后指定 FilterType 的类型为 ANNOTATION,也就是通过注解来过滤,最后的 value 则是Controller 注解类。配置之后,在 spring 扫描的时候,就会跳过 com.zz.cap2 包下,所有被 @Controller 注解标注的类。
结果:
orderController没有打印出来,排除成功
2.使用 includeFilters 来按照规则只包含某些包的扫描
修改配置类:
@ComponentScan(value = "com.zz.cap2", includeFilters = {@Filter(type = FilterType.ANNOTATION, value = Controller.class)})
public class Cap2MainConfig {
}
配置里面,应该是只包含 @Controller 注解的类才会被注册到容器中,为什么 @Service 注解的类也被注册了呢?这里涉及到 @ComponentScan 的一个 useDefaultFilters 属性的用法,该属性默认值为 true,也就是说 spring 默认会自动发现被 @Component、@Repository、@Service 和 @Controller 标注的类,并注册进容器中。要达到只包含某些包的扫描效果,就必须将这个默认行为给禁用掉(在 @ComponentScan 中将 useDefaultFilters 设为 false 即可)。
设置useDefaultFilters 为false
@ComponentScan(value = "com.zz.cap2", includeFilters = {@Filter(type = FilterType.ANNOTATION, value = Controller.class)}, useDefaultFilters = false)
public class Cap2MainConfig {
}
结果
1.2.2 添加自定义过滤规则
在前面使用过 @Filter 注解,里面的 type 属性是一个 FilterType 的枚举类型:
public enum FilterType {
ANNOTATION, //按照注解过滤
ASSIGNABLE_TYPE, //按照给定的类型
ASPECTJ, //使用ASPECTJ表达式
REGEX, //正则
CUSTOM //自定义规则
}
使用 CUSTOM 类型,就可以实现自定义过滤规则。
- 首先创建一个实现 TypeFilter 接口的 CustomTypeFilter 类,并实现其 match 方法。
public class CustomTypeFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
// 获取当前扫描到的类的注解元数据
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
// 获取当前扫描到的类的元数据
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 获取当前扫描到的类的资源信息
Resource resource = metadataReader.getResource();
if (classMetadata.getClassName().contains("vice")) {
return true;
}
return false;
}
}
这里简单对扫描到的类名进行判断,如果类名包含”vice“的就符合条件,也就会注入到容器中。
- 对 Cap2MainConfig进行修改,指定过滤类型为 Custom 类型,并指定 value 为 CustomTypeFilter.class。
@ComponentScan(value = "com.zz.cap2", includeFilters = {@Filter(type = FilterType.CUSTOM, value = CustomTypeFilter.class)}, useDefaultFilters = false)
public class Cap2MainConfig {
}
运行结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)