zoukankan      html  css  js  c++  java
  • 2021-07-01阅读小笔记:Spring ioc 之组件扫描

    1、包扫描指定扫描路径的方式有几种?分别如何指定?

    我们可以利用@ConponentScan注解对指定路径下的组件进行扫描,然后注入到Spring容器中。

    指定扫描路径有两种方式:指定包路径和指定类

    1.1 指定包路径

    例子:

    @ComponentScan(basePackages = "com.github.howinfun.demo.ioc.componentscan")
    public class Configuration {
    }
    

    容器会扫描指定的包路径下所有带注解「@Component及扩展注解」的类;指定包路径不但可以使用 basePackages 属性,还可以利用 value 属性,他们是同等的。

    1.2 指定类

    例子:

    @ComponentScan(basePackageClasses = Configuration.class)
    public class Configuration {
    }
    

    容器会扫描指定类所在路径及子路径下的所有带注解「@Component及扩展注解」的类。

    1.3 如何使用多个 @ComponentScan 注解

    我们可以利用Spring提供的 @ComponentScans 注解来配置多个 @ComponentScan

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    @Documented
    public @interface ComponentScans {
        ComponentScan[] value();
    }
    

    这个注解是在 Spring 4.3 中提供的,比较旧的版本看不到,也用不着。

    2、包扫描如何处理过滤规则?默认有哪几种规则?

    @ComponentScan 注解通过 includeFiltersexcludeFilters 属性来处理过滤规则,默认的是使用过滤规则是扫描带 @Repository、@Service、@Controller、@Component注解的组件,这个可看接口注释:

    /**
     * Indicates whether automatic detection of classes annotated with {@code @Component}
     * {@code @Repository}, {@code @Service}, or {@code @Controller} should be enabled.
     */
    boolean useDefaultFilters() default true;
    

    2.1 过滤规则支持:

    Spring 支持的所有过滤器类型:注解、指定类型、切面、正则、自定义.

    public enum FilterType {
    
    	/**
    	 * Filter candidates marked with a given annotation.
    	 * @see org.springframework.core.type.filter.AnnotationTypeFilter
    	 */
    	ANNOTATION,
    
    	/**
    	 * Filter candidates assignable to a given type.
    	 * @see org.springframework.core.type.filter.AssignableTypeFilter
    	 */
    	ASSIGNABLE_TYPE,
    
    	/**
    	 * Filter candidates matching a given AspectJ type pattern expression.
    	 * @see org.springframework.core.type.filter.AspectJTypeFilter
    	 */
    	ASPECTJ,
    
    	/**
    	 * Filter candidates matching a given regex pattern.
    	 * @see org.springframework.core.type.filter.RegexPatternTypeFilter
    	 */
    	REGEX,
    
    	/** Filter candidates using a given custom
    	 * {@link org.springframework.core.type.filter.TypeFilter} implementation.
    	 */
    	CUSTOM
    
    }
    

    2.2 例子:

    1、根据注解和指定类过滤

    @ComponentScan(basePackageClasses = {Configuration.class}
                                        // 指定类型为Color的组件不注入,包括子类
                    ,excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = Color.class)
                                        // 指定带@Component注解的组件不注入
                                        ,@ComponentScan.Filter(type = FilterType.ANNOTATION,value = Component.class)})
    public class Configuration {
    }
    

    2、自定义过滤器:

    @ComponentScan(basePackageClasses = {Configuration.class}
                                        // 指定类型为Color的组件不注入,包括子类
                    ,excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = Color.class),
                                        // 指定带@Component注解的组件不注入
                                    @ComponentScan.Filter(type = FilterType.ANNOTATION,value = Component.class),
                                    // 如果父类是Color,则不注入
                                    @ComponentScan.Filter(type = FilterType.CUSTOM,value = CustomFilter.class)})
    public class Configuration {
    }
    /**
     * 自定义组件扫描过滤器
     * 如果父类是Color,则返回true
     * @author winfun
     * @date 2021/7/1 3:09 下午
     **/
    public class CustomFilter implements TypeFilter {
    
        @Override
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
            /**
             * metadataReader :the metadata reader for the target class
             *      通过这个 Reader ,可以读取到正在扫描的类的信息(包括类的信息、类上标注的注解等)
             * metadataReaderFactory :a factory for obtaining metadata readers for other classes (such as superclasses and interfaces)
             *      借助这个 Factory ,可以获取到其他类的 Reader ,进而获取到那些类的信息
             *      可以这样理解:借助 ReaderFactory 可以获取到 Reader ,借助 Reader 可以获取到指定类的信息
             */
            // 获取类元数据
            ClassMetadata classMetadata = metadataReader.getClassMetadata();
            // 获取类注解元数据
            AnnotationMetadata aNnotationMetadata = metadataReader.getAnnotationMetadata();
            if (classMetadata.getSuperClassName().equals(Color.class)){
                return true;
            }
            return false;
        }
    }
    
    
    今天,你学习了吗
  • 相关阅读:
    Oracle 组件 系列 小结
    Oracle Data Mining 组件 说明
    GIS空间索引(有了思路代码还不是手到擒来)
    完成端口与高性能服务器程序开发(转)
    const? const ! 全解
    服务器架构
    SDL 源码分析(2)
    数据结构个算法学习笔记(2)
    高性能服务器架构 的几个注意点 (HighPerformance Server Architecture)
    GIS底层开发总结
  • 原文地址:https://www.cnblogs.com/Howinfun/p/14961111.html
Copyright © 2011-2022 走看看