@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
@interface EnableAutoConfiguration {
}
/**
* 导入Registrar类,该类主要是导入BasePackages类,保存了需要扫描的包的信息
*
* @see {@link AutoConfigurationPackages.BasePackages}
* @see {@link AutoConfigurationPackages.Registrar#registerBeanDefinitions}
* 该类的作用就是将标@AutoConfigurationPackage注解的类的包名封装成BasePackages对象,然后注册为Bean
* <p/>
* 对于其他外部,如果需要获取到SpringBoot需要自动扫描的包,则可以获取BasePackages这个Bean
* @see {@link AutoConfigurationPackages#get}
* BeanName固定为AutoConfigurationPackages.class.getName
*/
@Import(AutoConfigurationPackages.Registrar.class)
@interface AutoConfigurationPackage {
}
// 自动配置标注了@AutoConfigurationPackage类作为需要扫描的包名
class AutoConfigurationPackages {
private static final String BEAN = AutoConfigurationPackages.class.getName();
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
// 注册BasePackages的Bean对象,保存了标注@AutoConfigurationPackage注解的类对应的包名
AutoConfigurationPackages.register(registry, new PackageImport(metadata).getPackageName());
}
// 确定导入包的信息
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImport(metadata));
}
}
// 是否存在BasePackages的Bean对象
public static boolean has(BeanFactory beanFactory) {
return beanFactory.containsBean(BEAN) && !AutoConfigurationPackages.get(beanFactory).isEmpty();
}
// 获取需要扫描的包对应的Bean对象
public static List<String> get(BeanFactory beanFactory) {
try {
return beanFactory.getBean(BEAN, BasePackages.class).get();
} catch (NoSuchBeanDefinitionException ex) {
throw new IllegalStateException("Unable to retrieve @EnableAutoConfiguration base packages");
}
}
// 注册BasePackages的Bean对象,保存了标注@AutoConfigurationPackage注解的类对应的包名
public static void register(BeanDefinitionRegistry registry, String... packageNames) {
// 如果容器中包含"AutoConfigurationPackages" => BasePackages这个Bean
if (registry.containsBeanDefinition(BEAN)) {
// 获取该Bean的BeanDefinition
BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN);
// 添加构造参数
ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues();
// 将构造函数参数中的需要扫描的包名与给定的包名进行合并
String[] packages = AutoConfigurationPackages.addBasePackages(constructorArguments, packageNames);
// 重新添加进去
constructorArguments.addIndexedArgumentValue(0, packages);
return;
}
// 如果不存在BasePackagesBean,创建一个BasePackages的Bean对象
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(BasePackages.class);
// 添加构造参数
beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 注册Bean
registry.registerBeanDefinition(BEAN, beanDefinition);
}
// 将构造函数参数中的需要扫描的包名与给定的包名进行合并
private static String[] addBasePackages(ConstructorArgumentValues constructorArguments, String[] packageNames) {
String[] existing = (String[]) constructorArguments.getIndexedArgumentValue(0, String[].class).getValue();
Set<String> merged = new LinkedHashSet<>();
merged.addAll(Arrays.asList(existing));
merged.addAll(Arrays.asList(packageNames));
return StringUtils.toStringArray(merged);
}
// 保存标注了@AutoConfigurationPackage类的包名
public static final class PackageImport {
// 保存标注了@AutoConfigurationPackage类的包名
private final String packageName;
// 注解的元信息
public PackageImport(AnnotationMetadata metadata) {
// 获取到标注注解的类对应的类名
this.packageName = ClassUtils.getPackageName(metadata.getClassName());
}
public String getPackageName() {
return this.packageName;
}
}
// 保存所有需要扫描的包名
// 该对象会作为Spring中的Bean对象
public static final class BasePackages {
// 需要扫描的包名,该字段是通过beanDefinition.getConstructorArgumentValues()通过构造参数传递的
private final List<String> packages;
public BasePackages(String... names) {
List<String> packages = new ArrayList<>();
// 遍历所有的包名
for (String name : names) {
// 保存这些需要扫描的包名
packages.add(name);
}
this.packages = packages;
}
List<String> get() {
return this.packages;
}
}
}