一般在SpringBoot启动类上都会加上@SpringBootApplication
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration //就是一个加了这个Configuration注解标记,可以被Spring扫描到
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage //标记自动配置
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};
}
AutoConfigurationPackage 注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class) //导入Registrar组件
public @interface AutoConfigurationPackage {
}
Registrar类看下干了什么
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
//1 PackageImport
//2.register
//默认扫描@SpringBootApplication注解标志的类的所在在包及其子包
register(registry, new PackageImport(metadata).getPackageName());
}
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImport(metadata));
}
}
- PackageImport
private static final class PackageImport {
private final String packageName;
PackageImport(AnnotationMetadata metadata) {
//获取包名 -根据类名获取包名 //3
this.packageName = ClassUtils.getPackageName(metadata.getClassName());
}
ClassUtils.getPackageName(metadata.getClassName());
public static String getPackageName(String fqClassName) {
Assert.notNull(fqClassName, "Class name must not be null");
//获取最后一个分隔符
//private static final char PACKAGE_SEPARATOR = '.';
int lastDotIndex = fqClassName.lastIndexOf(PACKAGE_SEPARATOR);
//从0开始截取到lastDotIndex 就是包名
return (lastDotIndex != -1 ? fqClassName.substring(0, lastDotIndex) : "");
}
- register
public static void register(BeanDefinitionRegistry registry, String... packageNames) {
//private static final String BEAN = AutoConfigurationPackages.class.getName();
//第一次进来这个不会走会去 Else
if (registry.containsBeanDefinition(BEAN)) {
BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN);
ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues();
constructorArguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNames));
}
else {
//创建一个GenericBeanDefinition对象
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
//设置类型
beanDefinition.setBeanClass(BasePackages.class);
//添加参数
beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);
//设置权限
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//注册BeanDefinition
//private static final String BEAN = AutoConfigurationPackages.class.getName();
registry.registerBeanDefinition(BEAN, beanDefinition);
}
}