首先,我们先要找到springboot依赖的jar包是从哪里引入的。
pom.xml中的父依赖:spring-boot-starter-parent
点击进入父依赖(spring-boot-starter-parent),发现还有一级父依赖spring-boot-dependencies
点击进入最顶层的父依赖(spring-boot-dependencies),我们会发现,springboot的核心依赖都在父依赖中
在spring-boot-dependencies中,properties标签中为我们提供了默认的依赖版本,这也就是我们引入一下starter不需要指定版本号的原因!
启动类
首先,我们依次观察注解:
@SpringBootApplication注解
点击进入@SpringBootConfiguration注解:
点击进入@Configuration注解
返回@SpringBootApplication注解,点击进入@EnableAutoConfiguration注解
点击进入@AutoConfigurationPackage注解
注解结构
由此可知springboot启动类的注解结构:
@SpringBootApplication :标注为springboot应用,@SpringBootApplication是一个组合注解。
@SpringBootConfiguration : 核心!! ,顾名思义,可以看出这个注解的作用是关于springboot的配置。
@Configuration:spring的配置类。
@Component:说明这也是spring的一个组件。 @EnableAutoConfiguration : 核心!!,springboot自动装配的核心注解。
@AutoConfigurationPackage:自动配置包
@import({Registrar.class}) : 导入注册器 @import({AutoConfigurationimportSelector.class}) :导入自动装配选择器 @ComponentScan : 扫描包的注解
重点!! AutoConfigurationimportSelector.class
进入getAutoConfigurationEntry()方法:
进入getCandidateConfigurations()方法,发现自动装配扫描的是标注了@EnableAutoConfiguration注解的所有类
回过头 ,我们点进SpringFactoriesLoader.loadFactoryNames()方法中
我们发现,loadFactoryNames()中调用,loadSpringFactories()方法,在meta-INF/目录下,读取spring.factories文件
我们在spring-boot-autoconfigure这个jar包中发现了这个文件
打开看一下:
此时,我们发现了端倪,springboot自动装配会将meta-INF/spring.factories文件中配置自动装配到springboot中。
进入AutoConfigurationimportSelector.class,我们会发现 selectimports() 方法,此方法用来 选择组件
selectimports() 调用 this.getAutoConfigurationEntry(); 方法来 获取自动配置条目
this.getAutoConfigurationEntry(); 方法中,调用 List configurations = this.getCandidateConfigurations(annotationmetadata, attributes); 来 获取所有的配置
getCandidateConfigurations() 方法中,发现调用SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader())
this.getSpringFactoriesLoaderFactoryClass() 方法返回的就是EnableAutoConfiguration.class ,也就是说,自动装配扫描的是带有**@EnableAutoConfiguration** 注解的类。
回过头,我们进入 SpringFactoriesLoader.loadFactoryNames() 方法,发现 loadFactoryNames() 中调用,loadSpringFactories() 方法,在 meta-INF/ 目录下,读取 spring.factories 文件。
在 spring-boot-autoconfigure.jar下,我们发现了meta-INF/spring.factories 这个文件。
最终,也就是说,@EnableAutoConfiguration注解通过@SpringBootApplication注解被间接的标记在了SpringBoot的启动类上。通过@EnableAutoConfiguration注解找到meta-INF/spring.factories文件中的所有自动配置类,并对其加载,这些自动配置类都是以AutoConfiguration结尾来命名的。它实际上就是一个JavaConfig形式的IOC容器配置类,通过以Properties结尾命名的类中取得在全局配置文件中配置的属性,如server.port。
spring.factories
spring.factories中包括了所有的自动装配类
思考: 这么多自动配置为什么没有生效,需要导入对应的starter才能有作用?
例如WebMvcAutoConfiguration
当@ConditionalOnXXX,一些列条件注解满足时,配置才会生效。
扩展1: @Conditional、@ConditionalOnXXX
@ConditionalOnClass :只有在classpath下能找到kafkaTemplate类才会构建这个bean。
其他类似注解:
@Conditional(TestCondition.class) 这句代码可以标注在类上面,表示该类下面的所有@Bean都会启用配置,也可以标注在方法上面,只是对该方法启用配置。
@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
@ConditionalOnexpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnNotWebApplication(不是web应用)
扩展2:@EnableWebMvc 、WebMvcConfigurationSupport、WebMvcConfigurer和WebMvcConfigurationAdapter
@EnableWebMvc是什么
@EnableWebMvc实际上引入一个DelegatingWebMvcConfiguration,DelegatingWebMvcConfiguration继承了WebMvcConfigurationSupport。
,也就是说 @ConditionalOnMissingBean({WebMvcConfigurationSupport.class}) 为false,自动装配失效。
** implements WebMvcConfigurer** : 不会覆盖@EnableAutoConfiguration关于WebMvcAutoConfiguration的配置
@EnableWebMvc + implements WebMvcConfigurer : 会覆盖@EnableAutoConfiguration关于WebMvcAutoConfiguration的配置
extends WebMvcConfigurationSupport:会覆盖@EnableAutoConfiguration关于WebMvcAutoConfiguration的配置
extends DelegatingWebMvcConfiguration :会覆盖@EnableAutoConfiguration关于WebMvcAutoConfiguration的配置



