zoukankan      html  css  js  c++  java
  • 【Spring Boot】Spring Boot之使用ImportSelector类实现动态注册Bean

    一、ImportSelector类介绍

        可以通过指定的选择条件来决定哪些类被注册到Spring中。与ImportBeanDefinitionRegistrar类功能相似,通过@Import的方式来加载。

      也可以实现遗下Aware接口
        EnvironmentAware
        BeanFactoryAware
        BeanClassLoaderAware
        ResourceLoaderAware

        使用方式和ImportBeanDefinitionRegistrar一样通过@Import注解加载

    二、实现自定义的ImportSelector类

    解决的核心问题:如何指定我们想要加载的类

    1)第一种方式,在当前类中指定要加载的类

    /**
     * @author zhangboqing
     * @date 2019/12/18
     */
    public class HelloImportSelector implements ImportSelector {
    
        private static final String[] IMPORTS = {
                HelloService.class.getName(),
        };
    
    
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return IMPORTS;
        }
    }

    2)第二种方式,加载META-INF/spring.factories中指定key对应的类

    1、定义SpringFactoryImportSelector<T>类

    /**
     * @author zhangboqing
     * @date 2019/12/18
     */
    public class SpringFactoryImportSelector<T> implements DeferredImportSelector, BeanClassLoaderAware {
    
        private Class annotationClass;
    
        private ClassLoader beanClassLoader;
    
        protected SpringFactoryImportSelector() {
            // 用来获取泛型注解类即T代表的类型
            this.annotationClass = (Class<T>) GenericTypeResolver
                    .resolveTypeArgument(this.getClass(), SpringFactoryImportSelector.class);
        }
    
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            // 加载META-INF/spring.factories中key为HelloAnnotation注解对应的value类
            List<String> factories = new ArrayList<>(new LinkedHashSet<>(SpringFactoriesLoader
                    .loadFactoryNames(this.annotationClass, this.beanClassLoader)));
    
            return factories.toArray(new String[factories.size()]);
        }
    
        @Override
        public void setBeanClassLoader(ClassLoader classLoader) {
            this.beanClassLoader = classLoader;
        }
    
    }

    2、定义MySpringFactoryImportSelector,用来实现SpringFactoryImportSelector,指定对应的注解

    /**
     * @author zhangboqing
     * @date 2019/12/18
     */
    public class MySpringFactoryImportSelector extends SpringFactoryImportSelector<HelloAnnotation> {
    
    }

    或者在类中指定注解

    /**
     * @author zhangboqing
     * @date 2019/12/18
     */
    public class HelloAnnotationSpringFactoryImportSelector implements DeferredImportSelector, BeanClassLoaderAware {
    
        private Class annotationClass = HelloAnnotation.class;
    
        private ClassLoader beanClassLoader;
    
    
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            // 加载META-INF/spring.factories中key为HelloAnnotation注解对应的value类
            List<String> factories = new ArrayList<>(new LinkedHashSet<>(SpringFactoriesLoader
                    .loadFactoryNames(this.annotationClass, this.beanClassLoader)));
    
            return factories.toArray(new String[factories.size()]);
        }
    
        @Override
        public void setBeanClassLoader(ClassLoader classLoader) {
            this.beanClassLoader = classLoader;
        }
    
    }

              

  • 相关阅读:
    关于swift 单元测试的补充
    架构设计案例分析-高速公路收费运营管理平台
    可以落地的软件架构
    循序渐进地培养面向对象的思维方式
    动态规划初学
    求解惑
    github eclipse项目
    关于x86 i586之类
    Manifest intent filter翻译
    消息处理机制小结
  • 原文地址:https://www.cnblogs.com/756623607-zhang/p/12063817.html
Copyright © 2011-2022 走看看