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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值