Springboot-importSelector
Posted codingjav
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Springboot-importSelector相关的知识,希望对你有一定的参考价值。
ImportSelector接口概述
ImportSelector接口是至spring中导入外部配置的核心接口,在SpringBoot的自动化配置和@EnableXXX(功能性注解)都有它的存在。我们先来看一下ImportSelector接口的源码,如下所示。
public interface ImportSelector {
/**
* Select and return the names of which class(es) should be imported based on
* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
* @return the class names, or an empty array if none
*/
String[] selectImports(AnnotationMetadata importingClassMetadata);
/**
* Return a predicate for excluding classes from the import candidates, to be
* transitively applied to all classes found through this selector's imports.
* <p>If this predicate returns {@code true} for a given fully-qualified
* class name, said class will not be considered as an imported configuration
* class, bypassing class file loading as well as metadata introspection.
* @return the filter predicate for fully-qualified candidate class names
* of transitively imported configuration classes, or {@code null} if none
* @since 5.2.4
*/
@Nullable
default Predicate<String> getExclusionFilter() {
return null;
}
}
该接口文档上说的明明白白,其主要作用是收集需要导入的配置类,selectImports()方法的返回值就是我们向Spring容器中导入的类的全类名。如果该接口的实现类同时实现EnvironmentAware, BeanFactoryAware ,BeanClassLoaderAware或者ResourceLoaderAware,那么在调用其selectImports方法之前先调用上述接口中对应的方法,如果需要在所有的@Configuration处理完在导入时可以实现DeferredImportSelector接口。
在ImportSelector接口的selectImports()方法中,存在一个AnnotationMetadata类型的参数,这个参数能够获取到当前标注@Import注解的类的所有注解信息。
ImportSelector接口实例
首先,我们创建一个MySelector类实现ImportSelector接口,如下所示。
/**
* @import 注解中使用ImportSelector
* 自定义逻辑,返回需要导入的组件
*/
public class MySelector implements ImportSelector {
/**
* 返回值为需要导入到容器中的bean的全类名数组
* @param annotationMetadata
* @return
*/
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(MyScan.class.getName());
if (CollectionUtils.isEmpty(attributes)) {
return new String[0];
}
String[] basePackages = (String[]) attributes.get("basePackages");
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AssignableTypeFilter(Student.class));//这里实现包含,相当@ComponentScan includeFilters
scanner.addIncludeFilter(new AssignableTypeFilter(User.class));
//scanner.addExcludeFilter(new AssignableTypeFilter(Object.class));//这里可以实现排除,相当@ComponentScan excludeFilters
Set<String> classs = new HashSet<>();
for (String basePackage : basePackages) {
Set<BeanDefinition> components = scanner.findCandidateComponents(basePackage);
components.forEach(bean -> classs.add(bean.getBeanClassName()));
}
return classs.toArray(new String[0]);
}
}
Student
public class Student {
private String name;
public Student() {
this.name = "初始化数据";
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\\'' +
'}';
}
}
User:
@TableName(value = "user")
public class User extends BaseEntity{
@TableField(value = "name")
private String name;
@TableField(value = "sex")
private Integer sex;
}
上面已经把Student、User全类名返回到MySelector类的selectImports()方法中。
运行启动类,我们会发现这两个类已经加载进Spring容器。
以上是关于Springboot-importSelector的主要内容,如果未能解决你的问题,请参考以下文章