一、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; } }