其他分享
首页 > 其他分享> > 2021-07-01阅读小笔记:Spring ioc 之组件扫描

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

标签:01,07,Spring,指定,ComponentScan,Filter,注解,type,class
来源: https://blog.csdn.net/Howinfun/article/details/118398962