美文网首页
自定义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