zoukankan      html  css  js  c++  java
  • @ComponentScan 注解

    在配置类上添加 @ComponentScan 注解。该注解默认会扫描该类所在的包下所有的配置类,相当于xml的 <context:component-scan>。

    @ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中。

    新建三个类 

    @Controller
    public class OrderController {
    }
    @Service
    public class OrderService {
    }
    @Repository
    public class OrderDao {
    
    }

    配置类 

    @Configuration
    @ComponentScan("cn.qin.test")  //扫描该路径下的
    public class Config {
    }

    查看容器中的Bean

        AnnotationConfigApplicationContext app=new AnnotationConfigApplicationContext(Config.Class);
            String[] names=app.getBeanDefinitionNames();
            for (String name : names){
                System.out.println(name);
            }



    org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    org.springframework.context.annotation.internalRequiredAnnotationProcessor
    org.springframework.context.annotation.internalCommonAnnotationProcessor
    org.springframework.context.event.internalEventListenerProcessor
    org.springframework.context.event.internalEventListenerFactory
    Config
    orderController
    orderDao
    orderService

    
    

    源码分析

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Repeatable(ComponentScans.class)
    public @interface ComponentScan {
        /**
         * 对应的包扫描路径 可以是单个路径,也可以是扫描的路径数组
         * @return
         */
        @AliasFor("basePackages")
        String[] value() default {};
        /**
         * 和value一样是对应的包扫描路径 可以是单个路径,也可以是扫描的路径数组
         * @return
         */
        @AliasFor("value")
        String[] basePackages() default {};
        /**
         * 指定具体的扫描的类
         * @return
         */
        Class<?>[] basePackageClasses() default {};
        /**
         * 对应的bean名称的生成器 默认的是BeanNameGenerator
         * @return
         */
        Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
        /**
         * 处理检测到的bean的scope范围
         */
        Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
        /**
         * 是否为检测到的组件生成代理
         * Indicates whether proxies should be generated for detected components, which may be
         * necessary when using scopes in a proxy-style fashion.
         * <p>The default is defer to the default behavior of the component scanner used to
         * execute the actual scan.
         * <p>Note that setting this attribute overrides any value set for {@link #scopeResolver}.
         * @see ClassPathBeanDefinitionScanner#setScopedProxyMode(ScopedProxyMode)
         */
        ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
        /**
         * 控制符合组件检测条件的类文件   默认是包扫描下的  **/*.class
         * @return
         */
        String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
        /**
         * 是否对带有@Component @Repository @Service @Controller注解的类开启检测,默认是开启的
         * @return
         */
        boolean useDefaultFilters() default true;
        /**
         * 指定某些定义Filter满足条件的组件 FilterType有5种类型如:
         *                                  ANNOTATION, 注解类型 默认
                                            ASSIGNABLE_TYPE,指定固定类
                                            ASPECTJ, ASPECTJ类型
                                            REGEX,正则表达式
                                            CUSTOM,自定义类型
         * @return
         */
        Filter[] includeFilters() default {};
        /**
         * 排除某些过来器扫描到的类
         * @return
         */
        Filter[] excludeFilters() default {};
        /**
         * 扫描到的类是都开启懒加载 ,默认是不开启的
         * @return
         */
        boolean lazyInit() default false;
    }
    includeFilters 包含 
    excludeFilters 排除
    @Configuration
    @ComponentScan(value = "cn.qin.test",includeFilters = {
            @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),   // 注解类型  Controller
            @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {OrderService.class}),  //固定类型 是OrderService
    },useDefaultFilters
    = false) public class Config { }
    一定要设置useDefaultFilters =false 不然无效
     
    自定义 Filter
    public class CustomFilter implements TypeFilter {
        /**
         *
         * @param metadataReader  读取当前正在扫描类的信息
         * @param metadataReaderFactory  可以获取到其他任何类的信息
         * @return
         * @throws IOException
         */
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
            //获取当前类的注解信息
            AnnotatedTypeMetadata annotatedTypeMetadata=metadataReader.getAnnotationMetadata();
            //获取正在扫描类的信息
            ClassMetadata classMetadata=metadataReader.getClassMetadata();
            //获取当前类资源(类的路径)
            Resource resource = metadataReader.getResource();
    
            String className=classMetadata.getClassName();
            System.out.println("正在扫描的类:"+className);
    
            if(className.contains("Controller")) //类名包含了Controller的才被放到容器中
            {
                return true;
            }
    
            return false;
    
        }
    }
     

      



  • 相关阅读:
    第2课 C 到 C++ 的升级
    第1课 学习 C++ 的意义
    归并排序
    插入排序与希尔排序
    选择排序
    冒泡排序
    CodeSignal 刷题 —— almostIncreasingSequence
    CodeSignal 刷题 —— matrixElementSum
    Python3 序列解包
    单星号变量(*)和双星号变量(**)的用法
  • 原文地址:https://www.cnblogs.com/qin1993/p/11661273.html
Copyright © 2011-2022 走看看