美文网首页
自定义ImportSelector

自定义ImportSelector

作者: 一生逍遥一生 | 来源:发表于2020-05-01 11:57 被阅读0次

在日常开发的过程中,有可能需要自定义导入一些bean,有可能是按照自定义的包进行扫描,将bean导入到IOC容器中。

package com.edu.spring5;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AspectJTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.StringUtils;
import java.util.*;
public class CustomImportSelector implements ImportSelector {
    /**
     * 表达式:aspectj表达式
     */
    private String expression;

    private String customPackage;

    public CustomImportSelector() {
        try {
            Properties properties = PropertiesLoaderUtils.loadAllProperties("custom.properties");
            expression = properties.getProperty("custom.import.selector.expression");
            customPackage = properties.getProperty("custom.import.selector.package");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 实现要导入类的字节码
     * 需求:
     *      要导入的过滤规则typefilter采用aspectj方式
     * @param importingClassMetadata
     * @return
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        /**
         *  定义扫描包的名称
         */
        List<String> basePackages = null;
        /**
         * 获取@Import注解上是否有@ComponentScan注解
         */
        if (importingClassMetadata.hasAnnotatedMethods(ComponentScan.class.getName())){
            /**
             * 取出componentscan的值
             */
            Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
            basePackages = new ArrayList<>(Arrays.asList((String[]) annotationAttributes.get("basePackages")));
            if (basePackages == null || basePackages.size() == 0){
                String basePackage = null;
                try {
                    basePackage = Class.forName(importingClassMetadata.getClassName()).getPackage().getName();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                /**
                 * 将包放入到basePackages中
                 */
                basePackages = new ArrayList<>();
                basePackages.add(basePackage);
            }
        }
        if (!StringUtils.isEmpty(customPackage)){
            basePackages.add(customPackage);
        }
        /**
         * 创建类路径扫描器,参数的含义,表明不使用默认过滤规则
         */
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        /**
         * 创建类型过滤器
          */
        TypeFilter typeFilter = new AspectJTypeFilter(expression,CustomImportSelector.class.getClassLoader());
        /**
         * 将类型过滤器添加到扫描器中
         */
        scanner.addIncludeFilter(typeFilter);
        final Set<java.lang.String> classes = new HashSet<>();
        for (String basePackage:basePackages){
            scanner.findCandidateComponents(basePackage).forEach(beanDefinition->{
                classes.add(beanDefinition.getBeanClassName());
            });
        }
        return classes.toArray(new String[classes.size()]);
    }
}

这个样例,需要添加依赖:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.5</version>
</dependency>

参考文献

自定义importselector

相关文章

网友评论

      本文标题:自定义ImportSelector

      本文链接:https://www.haomeiwen.com/subject/sznfghtx.html