使用springboot的Bean扫描器完成自定义类型/自定义注解的class扫描

有时我们需要在整个项目内扫描一些类型的类,有可能是实现了某个类型的子类,或者是加了某注解的类,这时候我们可以借助Spring的Bean扫描来完成这些功能。

本博客参考 博客 springboot自定义注解,项目启动时扫描注解类并注入容器
, 感谢大佬!

思路

spring为了能支持扫描,提供了 ClassPathScanningCandidateComponentProvider ,可以借助他来扫描。下面是代码:

@AllArgsConstructor
public class DataPermissionRegister {
    /**
     * 资源加载器
     */
    private final ResourceLoader resourceLoader;
    /**
     * 环境
     */
    private final Environment environment;

    @PostConstruct
    public void init() {
        if (log.isInfoEnabled()){
            log.info("start DataPermissionRegister ");
        }

        ClassPathScanningCandidateComponentProvider scanner = getScanner();
        scanner.setResourceLoader(resourceLoader);

        // 设置扫描器scanner扫描的过滤条件 还支持扫描指定类型(包括继承他的类)  AssignableTypeFilter
        AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(DataPermission.class);
        scanner.addIncludeFilter(annotationTypeFilter);

        // 获取指定要扫描的basePackages
        Set<String> basePackages = Set.of("com.yonyou", "com.changan");

        // 遍历每一个basePackages
        for (String basePackage : basePackages) {
            // 通过scanner获取basePackage下的候选类(有标@SimpleRpcClient注解的类)
            Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
            // 遍历每一个候选类,如果符合条件就把他们注册到容器
            for (BeanDefinition candidateComponent : candidateComponents) {
                if (candidateComponent instanceof AnnotatedBeanDefinition beanDefinition) {
                    // candidateComponent 有很多class的信息,下面举例是获取class上的指定注解
                    AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
        Map<String, Object> dataPermissionAttrs = annotationMetadata.getAnnotationAttributes(DataPermission.class.getCanonicalName());
        // ...剩余处理,注册 或者其他
                }
            }
        }

        if (log.isInfoEnabled()){
            log.info("dataPermissionRegister init success!");
        }
    }

    

    /**
     * 创建扫描器
     */
    protected ClassPathScanningCandidateComponentProvider getScanner() {
        return new ClassPathScanningCandidateComponentProvider(false, environment) {
            @Override
            protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
                boolean isCandidate = false;
                if (beanDefinition.getMetadata().isIndependent()) {
                // 注解类型的class就不要了
                    if (!beanDefinition.getMetadata().isAnnotation()) {
                        isCandidate = true;
                    }
                }
                return isCandidate;
            }
        };
    }
}

注意,这里扫描做出来class并没有把他注册到spring容器中,如果有这个需要,请参考上面提到的播客。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值