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

}

 

 

 

          


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM