1.套娃的起点
1.1 @SpringBootApplication
- 被SpringBootApplication所标注的就是SpringBoot应用(主配置类)
1.2 @SpringBootApplication
代码 (注解)
@Target(ElementType.TYPE) //元注解 指定当前自定义注解可标注的位置
@Retention(RetentionPolicy.RUNTIME) //元注解 指定当前自定义注解可以运行的环境
@Documented //元注解 注解可生成在DOC文档
@Inherited //元注解 被这个注解标识的自定义注解 被某个类使用时,那么他的子类及其子类也会有当前注解(被@Inherited表示的自定义注解)
@SpringBootConfiguration //SpringBoot配置文件 被@Configuration注解
@EnableAutoConfiguration //自动装配重头戏 下面展开来讲这个东东
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) //扫描包
2. 自动装配原理 @EnableConfiguration
2.1 代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage //自动配置包
@Import(AutoConfigurationImportSelector.class) //导入 自动配置导入选择器(可以先不了解)
2.1.1 AutoConfigurationPack
-
作用
- 把标注了
@SpringBootApplication
注解的类的同级包及其子包下的类注册到 Spring 容器中
- 把标注了
-
代码
AutoConfigurationPack
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(AutoConfigurationPackages.Registrar.class) //注意这里 导入了 "自动配置包注册"
AutoConfigurationPackages.Registrar.class
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0])); } //从下图可以看到 我只有一个包` renchensbc` 而`getPackageNames` 的result 也只有这个包名 更深的就不用去探究了
2.1.2 @Import(AutoConfigurationImportSelector.class)
-
AutoConfigurationImportSelector.class
-
作用
- 把META-INF/spring.factories里面的 全限定类名返回并注册到Spring容器中
-
代码
- 这里专注其中一个方法 开端
- 言简意赅 它叫选择导入 那选择了哪些东西
public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { //判断是否自动导入 return NO_IMPORTS; } AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); }
- 那这些实体是怎么来的呢
getAutoConfigurationEntry(annotationMetadata);
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } AnnotationAttributes attributes = getAttributes(annotationMetadata); List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); configurations = removeDuplicates(configurations); Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = getConfigurationClassFilter().filter(configurations); fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry(configurations, exclusions); }
-
在这里需要注意
AutoConfigurationEntry(configurations, exclusions)
参数 -
configuration 是怎么来的?,它里面都是什么东西?
- 它里面有要注册的自动装配类
META-INF/spring.factories
- 从
getCandidateConfigurations(annotationMetadata, attributes)
返回
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; }
- 我们来看
getCandidateConfigurations
代码- 返回值:List 哪里来的?
SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());
- 加载
META-INF/spring.factories
得到的
- 加载
- 返回值:List 哪里来的?
loadFactoryNames
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) { String factoryTypeName = factoryType.getName(); return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList()); }
-
可以先查看一下调用它
loadFactoryNames
时传入的参数getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader()
getSpringFactoriesLoaderFactoryClass()
protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class; }
-
return
EnableAutoConfiguration.class
- 介东西又是个啥?
org.springframework.boot.autoconfigure.EnableAutoConfiguration
- 可以在
META-INF/spring.factories
找到- 需要自动配置类全限定类名给这个类
org.springframework.boot.autoconfigure.EnableAutoConfiguration
- 需要自动配置类全限定类名给这个类
-
return 这个列表
- 它里面有要注册的自动装配类
- 这里专注其中一个方法 开端
-