注解
@ComponentScan 通过此注解来设置包,类的扫描规则。
一、配置文件开发
在 Spring 配置文件中使用 <context:component-scan>
标签来设置包的扫描规则。

二、注解开发
在原来的配置类上面,可以添加 @ComponentScan 注解来添加类的扫描规则。
@ComponentScan 注解中使用 value 属性来指定要扫描的包
@Configuration
@ComponentScan(value = "com.njf")//value 指定要扫描的包
public class MainConfig {
/**
* 使用 @Bean 注册一个 bean 组件,bean 类型是返回值的类型,id 默认是方法名即(person)
* 修改 id 名
* 1)修改方法名;
* 2)注解中 value 值即 bean 的 id
* @return
*/
@Bean(name = "Person")
public Person person01() {
return new Person("李四", 20);
}
}
三、@ComponentScan 常用属性方法
1、指定扫描的包
value() 和 basePackages() 可以指定扫描要的包;

这两个方法都是一样,可以使用 value 或者 basePackages() 来指定扫描的包;(可以使用表达式)
2、排除指定组件
excludeFilters = Filter[] 指定扫描的时候按照指定规则排除那些组件
示例:按照注解规则排除指定的组件
@ComponentScan(value = "com.njf", excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})
})
3、包含指定组件
includeFilters = Filter[] 指定扫描的时候按照指定只包含那些组件(把 useDefaultFilters 设置为 false)
示例:按照指定规则扫描对应的组件
@ComponentScan(value = "com.njf", includeFilters = {
@ComponentScan.Filter(type=FilterType.ANNOTATION, classes= {Controller.class}), //使用注解
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, classes = {BookService.class}) //使用类的类型
}, useDefaultFilters = false)
注意:默认是扫描所有的组件,一定要禁用掉,然后按照指定的规则扫描,一定要设置 useDefaultFilters 设置为 false,即不扫描全部的,只扫描指定的类。
四、自定义扫描规则
在上面的扫描规则中,都是通过添加 Filter 来指定扫描规则的。
在 @ComponentScan.Filter 注解中有一个 type() 属性方法,指定了通过哪一种规则来进行扫描的。
源码:
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
FilterType type() default FilterType.ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
默认使用的按照注解的类型来扫描的。
FilterType 枚举类中定义了如下几种方式的扫描规则:
FilterType.ANNOTATION 按照注解的类型
FilterType.ASSIGNABLE_TYPE 按照给定的类型
FilterType.ASPECTJ 按照 aspectj 表达式
FilterType.REGEX 按照正则表达式来指定
FilterType.CUSTOM 使用自定义规则
可以看到我们可以自定义 Filter 来进行包的扫描规则。

对于自定义 Filter,需要是 TypeFilter 的实现类。
创建自定义的 Filter,定义一个普通类,实现 TypeFilter:
public class MyTypeFilter implements TypeFilter {
/*
* @param metadataReader : 读取到的当前正在扫描的类的信息
* @param metadataReaderFactory : 可以获取到其他任何类信息
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println("--->" + className);
if (className.contains("er")) { //表示当扫描的类名中有er时,就会包含该类
return true;
}
return false;
}
}
使用自定义的过滤规则进行扫描:
@ComponentScan(value = "com.njf", includeFilters = {
@ComponentScan.Filter(type=FilterType.ANNOTATION, classes= {Controller.class}), //使用注解
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, classes = {BookService.class}), //使用类的类型
@ComponentScan.Filter(type=FilterType.CUSTOM, classes = {MyTypeFilter.class}) //使用自定义规则
}, useDefaultFilters = false)
五、其他
1、@ComponentScan 重复使用
在 Spring 的高版本(4.0 以上)声明为了重复注解:

可以在配置类上写多个 @ComponentScan 扫描规则:
@Configuration
@ComponentScan(value = "com.njf", excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})
})
@ComponentScan(value = "com.njf", includeFilters = {
@ComponentScan.Filter(type=FilterType.ANNOTATION, classes= {Controller.class}), //使用注解
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, classes = {BookService.class}), //使用类的类型
@ComponentScan.Filter(type=FilterType.CUSTOM, classes = {MyTypeFilter.class}) //使用自定义规则
}, useDefaultFilters = false)
public class MainConfig {
/**
* 使用 @Bean 注册一个 bean 组件,bean 类型是返回值的类型,id 默认是方法名即(person)
* 修改 id 名
* 1)修改方法名;
* 2)注解中 value 值即 bean 的 id
* @return
*/
@Bean(name = "Person")
public Person person01() {
return new Person("李四", 20);
}
}
- 如果是 JDK8,可以像上面写多个包扫描器 @ComponentScan;
- 如果不是 JDK8,可以使用下面的 @ComponentScans 指定多个包扫描规则;
2、使用@ComponentScans
使用 @ComponentScans 注解,可以在 value 数组里面放多个 @ComponentScan;
@ComponentScans 和 @ComponentScan 注解不可以同时使用!
@Configuration
@ComponentScans(
value = {
@ComponentScan(value = "com.njf", excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})
}),
@ComponentScan(value = "com.njf", excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class})
})
}
)
public class MainConfig {
/**
* 使用 @Bean 注册一个 bean 组件,bean 类型是返回值的类型,id 默认是方法名即(person)
* 修改 id 名
* 1)修改方法名;
* 2)注解中 value 值即 bean 的 id
* @return
*/
@Bean(name = "Person")
public Person person01() {
return new Person("李四", 20);
}
}
结论:如果有多个 @ComponentScan 时,各个 @ComponentScan 扫描到的类的交集都会被注册到 spring 容器中。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
2019-11-12 Float型 与 Double型数据的存储方式