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
注解通过 includeFilters
和 excludeFilters
属性来处理过滤规则,默认的是使用过滤规则是扫描带 @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