2.1 源码分析
pom.xml
spring-boot-starter-parent ===》spring-boot-dependencies
-
spring-boot-dependencies
管理了 SpringBoot 的核心依赖,以及他们的版本号- 因此,配置相关依赖的时候,并不需要指定版本号。
启动器
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
-
spring-boot-starter-web
会自动导入 web 环境所有的依赖 -
springboot 将所有的功能场景,都变为一个一个的启动器,想要哪种功能,就只需要导入相应的启动器就好。
-
官方文档启动器地址:https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
主程序
//程序主入口 本身既是一个Spring 的组件
//@SpringBootApplication 标注这个类是一个springboot的应用 启动类下的所有资源被导入
@SpringBootApplication
public class HelloworldApplication {
public static void main(String[] args) {
// 将springboot应用启动 通过反射,加载上面的类,并传递参数
SpringApplication.run(HelloworldApplication.class, args);
}
}
-
注解:
-
@SpringBootApplication @SpringBootConfiguration //springboot的配置 @Configuration //说明该类是一个spring的配置类 @Component //说明该类是一个spring的组件 @EnableAutoConfiguration //开启自动装配 @AutoConfigurationPackage //自动配置包 @Import({Registrar.class}) //导入自动配置包注册器 metadata //元数据 @Import({AutoConfigurationImportSelector.class}) //自动配置导入选择器 …… 见下文 @ComponentScan //扫描包 //接@Import({AutoConfigurationImportSelector.class})下面 //获取所有的配置 List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); //点入getCandidateConfigurations 获得候选的配置 ……见下文
-
获取候选的配置
-
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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; }
-
loadFactoryNames
首先加载了:-
getBeanClassLoader()
-
getSpringFactoriesLoaderFactoryClass()
@EnableAutoConfiguration
包含了EnableAutoConfiguration.class
- 而
@SpringBootApplication
正好包含了@EnableAutoConfiguration
- 而
@SpringBootApplication
被注在了主程序的类(启动类)上,也就相当于**把启动类下的所有资源导入了进去**
-
-
同一页面下的
Assert.notEmpty
-
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."); //断言.非空(确保spring.factories配置文件的正确)
-
META-INF/spring.factories
是一个自动配置的核心文件,包含了各种配置
-
-
再看
loadFactoryNames
,点进去,看到-
SpringFactoriesLoader
spring 工厂的加载
-
如上文所说的,通过
@SpringBootApplication
加载了启动类下的资源
- 如此==得到了所有的配置类==
-
-
2.2 脑图分析
总结:SpringBoot 所有的自动配置都是在启动的时候扫描注册加载,spring.factories
所有的自动配置都在该文件中,但是是否生效,要看是否配置了相应的springboot-starter-XXX,如果配置了,那么该启动器下所有的自动装配即会生效。
- SpringBoot 在启动的时候,从类路径spring-boot-autoconfigure-2.4.5.jar/META-INF/spring.factories下,获取指定的值。
- 将这些自动配置的类导入容器,自动配置就会生效(见下文)
- 以前需要手动配置的东西,现在springboot代理做了
- 整个JavaEE,解决方案和所有的自动配置都在
spring-boot-autoconfigure-2.4.5.jar
包下 - 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器。
- 容器中会存在非常多的
XXXautoconfigure
的文件(包含大量的@Bean (配置为组件)),就是这些类给容器中导入了这个场景需要的所有组件;并自动装配(@Configuration,就是Spring中的JavaConfig) - 有了自动配置类,就免去了我们手动编写配置文件的工作!
2.3 小结
以上原理都是在讲@SpringBootApplication
这个注解所扮演的功能,即==自动装配的核心角色==,而SpringApplication.run(HelloworldApplication.class, args);
即启动,则见下文。