一、@ComponentScan注解属性
value:指定要扫描的package;
includeFilters=Filter[]:指定只包含的组件
excludeFilters=Filter[]:指定需要排除的组件;
useDefaultFilters=true/false:指定是否需要使用Spring默认的扫描规则:被@Component, @Repository, @Service, @Controller或者已经声明过@Component自定义注解标记的组件;
在过滤规则Filter中:
FilterType:指定过滤规则,支持的过滤规则有
ANNOTATION:按照注解规则,过滤被指定注解标记的类;
ASSIGNABLE_TYPE:按照给定的类型;
ASPECTJ:按照ASPECTJ表达式;
REGEX:按照正则表达式
CUSTOM:自定义规则;
value:指定在该规则下过滤的表达式;
二、@ComponentScan注解过滤规则说明
1. 扫描指定类文件
@ComponentScan(basePackageClasses = Person.class)
2. 扫描指定包,使用默认扫描规则,即被@Component, @Repository, @Service, @Controller或者已经声明过@Component自定义注解标记的组件;
@ComponentScan(value = "com.yibai")
3. 扫描指定包,加载被@Component注解标记的组件和默认规则的扫描(因为useDefaultFilters默认为true)
@ComponentScan(value = "com.yibai", includeFilters = { @Filter(type = FilterType.ANNOTATION, value = Controller.class) }, useDefaultFilters = false)
4. 扫描指定包,只加载Person类型的组件
@ComponentScan(value = "com.yibai", includeFilters = { @Filter(type = FilterType.ASSIGNABLE_TYPE, value = Person.class) }, useDefaultFilters = false)
5. 扫描指定包,过滤掉被@Component标记的组件
@ComponentScan(value = "com.yibai", excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = Component.class) })
6. 扫描指定包,自定义过滤规则
@ComponentScan(value = "com.yibai", includeFilters = { @Filter(type = FilterType.CUSTOM, value = ColorBeanLoadFilter.class) }, useDefaultFilters = true)
三、代码示例
创建6个类
@Component
public class ColorBean {
}
/**
* 1. 扫描指定类文件
* @ComponentScan(basePackageClasses = ColorBean.class)
* 2. 扫描指定包,使用默认扫描规则,即被@Component, @Repository, @Service, @Controller或者已经声明过@Component自定义注解标记的组件;
* @ComponentScan(value = "com.bussines.test")
* 3. 扫描指定包,加载被@Component注解标记的组件和默认规则的扫描(因为useDefaultFilters默认为true)
* @ComponentScan(value = "com.bussines.test", includeFilters = { @Filter(type = FilterType.ANNOTATION, value = Controller.class) }, useDefaultFilters = false)
* 4. 扫描指定包,只加载Person类型的组件
* @ComponentScan(value = "com.bussines.test", includeFilters = { @Filter(type = FilterType.ASSIGNABLE_TYPE, value = ColorBean.class) }, useDefaultFilters = false)
* 5. 扫描指定包,过滤掉被@Component标记的组件
* @ComponentScan(value = "com.bussines.test", excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = Component.class) })
* 6. 扫描指定包,自定义过滤规则
* @ComponentScan(value = "com.bussines.test", includeFilters = { @Filter(type = FilterType.CUSTOM, value = ColorBeanLoadFilter.class) }, useDefaultFilters = false)
*/
@Configuration
@ComponentScan(value = "com.bussines.test")
public class ColorConfiguration {
}
@Controller
public class ColorController {
}
@Repository
public class ColorDao {
}
@Service
public class ColorService {
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class JuniterTestColor {
@Test
public void testImportBean(){
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ColorConfiguration.class);
String [] beanNames=annotationConfigApplicationContext.getBeanDefinitionNames();
for(String item:beanNames){
System.out.println("bean名称:"+item+"--- 输出bean对象:"+annotationConfigApplicationContext.getBean(item));
}
}
}
输出结构为:
bean名称:colorBean— 输出bean对象:com.bussines.test.ColorBean@609ad016
bean名称:colorController— 输出bean对象:com.bussines.test.ColorController@da9374c
bean名称:colorDao— 输出bean对象:com.bussines.test.ColorDao@34647f58
bean名称:colorService— 输出bean对象:com.bussines.test.ColorService@14b96c1e
其余五种情况可以更换ColorConfiguration中@ComponentScan进行测试。
自定义过滤规则:
创建自定义规则类ColorBeanLoadFilter.java
public class ColorBeanLoadFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
// 当前被扫描类的注解信息
@SuppressWarnings("unused")
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
// 当前被扫描类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 当前被扫描类资源信息
@SuppressWarnings("unused")
Resource resource = metadataReader.getResource();
try {
String className = classMetadata.getClassName();
Class<?> forName = Class.forName(className);
if (ColorBean.class.isAssignableFrom(forName)) {
// 如果是Color的子类,就加载到IOC容器
return true;
}
} catch (ClassNotFoundException e) {
// e.printStackTrace();
}
return false;
}
}
如果是Color的子类,就加载到IOC容器,输出结果中没有了controller,service,Repository。
输出结果:
bean名称:colorBean— 输出bean对象:com.bussines.test.ColorBean@3bc20984