当需要扫描一个包下的所有注解时,可以在XML文件中进行配置:
<!--包扫描,只要标注了@Controller、@Service、@Reposotory、@Component就可以被加载到spring bean容器-->
<context:component-scan base-package="spring_annotation.com.anno"></context:component-scan>
也可以使用@ComponentScan来完成,@ComponentScans完成多重注解。
实例:
package spring_annotation.com.anno.config; import org.springframework.context.annotation.*; import spring_annotation.com.anno.bean.Person; /** * @author Millet * @date 2020/6/8 20:21 */ //配置类 == 配置文件 @Configuration //告诉Spring这是一个配置类 //@ComponentScan(value = "spring_annotation.com.anno")//类似于xml配置文件中的context包扫描 //@ComponentScan(value = "spring_annotation.com.anno", includeFilters = { // @ComponentScan.Filter(type= FilterType.ANNOTATION,classes = {Controller.class, Service.class}) //},useDefaultFilters = false)//取消使用默认过滤 //@ComponentScan value:指定要扫描的包 //excludeFilters = Filter[],指定扫描的时候按照什么规则排除那些组件 //cludeFilters = Filter[],指定扫描的时候按照什么规则只需要那些组件 //@ComponentScan是可多重注解的,一般使用ComponentScans @ComponentScans( @ComponentScan(value = "spring_annotation.com.anno", 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("person") //给容器注册一个bean;类型为返回值类型,id默认是方法名或者自定义 public Person getPerson(){ return new Person("lisi",20); } }
@ComponentScan源码
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Repeatable(ComponentScans.class) public @interface ComponentScan { @AliasFor("basePackages") String[] value() default {}; @AliasFor("value") String[] basePackages() default {}; Class<?>[] basePackageClasses() default {}; Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class; Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class; ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT; String resourcePattern() default "**/*.class";
//默认使用默认的过滤器,当使用自己要置为false boolean useDefaultFilters() default true;
//指定扫描的时候按照什么规则只需要那些组件 ComponentScan.Filter[] includeFilters() default {};
//指定扫描的时候按照什么规则排除那些组件 ComponentScan.Filter[] excludeFilters() default {}; boolean lazyInit() default false; @Retention(RetentionPolicy.RUNTIME) @Target({}) public @interface Filter {
//FilterType有五种
//ANNOTATION
//ASSIGNABLE_TYPE
//ASPECTJ
//REGEX
//CUSTOM
FilterType type() default FilterType.ANNOTATION; @AliasFor("classes") Class<?>[] value() default {}; @AliasFor("value") Class<?>[] classes() default {}; String[] pattern() default {}; } }
自定义扫描过滤器
public class MyTypeFilter implements TypeFilter { /** * * @param metadataReader 读取到的当前正在扫描的类 * @param metadataReaderFactory 可以获取到任何其他类的信息 * @return * @throws IOException */ @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //获取当前类注解的信息 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); //获取当前类的类信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); String className = classMetadata.getClassName(); //获取当前类的类资源 Resource resource = metadataReader.getResource(); System.out.println("--->"+className); if(className.contains("er")){ return true; } return false; } }