Spring组件注册@ComponentScan注解

一、@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

你可能感兴趣的:(spring)