注解-组件注册02-@ComponentScan

  当需要扫描一个包下的所有注解时,可以在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;
    }
}

 

posted @ 2020-06-09 20:28  Qmillet  阅读(159)  评论(0编辑  收藏  举报