【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;
    }

}

 

 

 

          

posted @ 2019-12-18 21:32  N!CE波  阅读(1735)  评论(0编辑  收藏  举报