Spring之TypeFilter

TypeFilter, 望名思义,根据类型进行过滤。它是一个接口,有且只有一个match方法需要实现。
@FunctionalInterface
public interface TypeFilter {
    boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException;
}

它一般使用在哪些场合呢?

        答:可能有很多场合,但我目前只知道一个,那就是用于Bean的自动扫描加载。

它又如何使用呢?

        答:有一个注解会使用它,那就是@ComponentScan注解,它有一个属性:includeFilters;需要指定类型为Filter的参数。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
	@AliasFor("basePackages")
	String[] value() default {};

	@AliasFor("value")
	String[] basePackages() default {};

	Class<?>[] basePackageClasses() default {};

	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

	Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;

	ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

	String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;

	boolean useDefaultFilters() default true;

	Filter[] includeFilters() default {};

	Filter[] excludeFilters() default {};

	boolean lazyInit() default false;

	@Retention(RetentionPolicy.RUNTIME)
	@Target({})
	@interface Filter {

		FilterType type() default FilterType.ANNOTATION;

		@AliasFor("classes")
		Class<?>[] value() default {};

		@AliasFor("value")
		Class<?>[] classes() default {};

		String[] pattern() default {};

	}

}

下来,给大家一个示例:

1. 先定义一个实现TypeFilter接口的类

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

public class MyTypeFilter implements TypeFilter {
    /**
     *
     * @param metadataReader 读取到的当前正在扫描的类的信息
     * @param metadataReaderFactory 可以获取到其他任何类信息
     * @return
     * @throws IOException
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //获取当前类注解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();

        //获取当前正在扫描的类的类信息
        ClassMetadata classMetadata =  metadataReader.getClassMetadata();

        //获取当前类资源(类的路径)
        Resource resource = metadataReader.getResource();

        String className = classMetadata.getClassName();

        System.out.println("---: " + className);
           
        //类名包含Service的类都会被装载为Bean
        if (className.contains("Service")){
            return true;
        }

        return false;
    }
}

2. 其次,注册一个配置类。

这个配置类指定了扫描的根目录(value="xxx"字段),并且,过滤方式是MyTypeFilter类(classes =xxx),也就是我们自定义的类。

使用默认过滤器为true,也就是使用@Component, @Service,  @Controller注解的类也会被注册到实例中。

@ComponentScan(value = "com.cosseen.bean", includeFilters = {
                @ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class)
        }, useDefaultFilters = true)
public class MyFilterConfig {
}

3. 常见一个App类,调用配置类加载Bean。

public class AppFilter {
    public static void main(String[] args){
        ApplicationContext ctx = new AnnotationConfigApplicationContext(MyFilterConfig.class);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}

4. 结果:

在com.cosseen.bean目录下的类名包含Service的类,会被自动装载到上下文中。使用传统注解的组件也会自动装载到上下文中。

相关推荐

  1. SpringTypeFilter

    2024-01-02 12:56:04       57 阅读
  2. Spring Boot ModelFactory

    2024-01-02 12:56:04       51 阅读
  3. Spring事务(2)

    2024-01-02 12:56:04       48 阅读
  4. Spring注解开发

    2024-01-02 12:56:04       63 阅读
  5. SpringIOC

    2024-01-02 12:56:04       42 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-02 12:56:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-02 12:56:04       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-02 12:56:04       87 阅读
  4. Python语言-面向对象

    2024-01-02 12:56:04       96 阅读

热门阅读

  1. vivado XDC优先级

    2024-01-02 12:56:04       53 阅读
  2. 姿态估计:DiffPose

    2024-01-02 12:56:04       59 阅读
  3. 【数值分析】choleskey分解,matlab实现

    2024-01-02 12:56:04       62 阅读
  4. vue3插件:ace-builds封装ace-editor

    2024-01-02 12:56:04       62 阅读
  5. hasattr() 函数的理解

    2024-01-02 12:56:04       63 阅读
  6. LTE:连接你我,5G时代的前奏

    2024-01-02 12:56:04       60 阅读
  7. Golang leetcode206 翻转链表 迭代 递归 双指针

    2024-01-02 12:56:04       60 阅读
  8. js 控制页面滚动

    2024-01-02 12:56:04       67 阅读
  9. ECS36B computer

    2024-01-02 12:56:04       46 阅读