从Spring到SpringBoot
一、从Spring到SpringBoot
随着Spring的生态体系越来越壮大,Spring也变得越来越复杂,越来越臃肿。比如你想基于一套SSM的框架进行开发,那么你需要配置很多的东西,整合很多的东西。
因此Spring Boot应运而生。那么他基于什么变得简单呢?
就是:约定大于配置
什么是SpringBoot?
SpringBoot使创建独立运行、生产级别的Spring应用变得容易,你可以直接运行它。大部分SpringBoot应用仅仅需要少量的配置就可以使用。
SpringBoot的特性:
- 创建独立运行的Spring应用
- 直接嵌入Tomcat或Jetty,Undertow,无需部署WAR包
- 提供starter依赖简化配置
- 在必要时自动化配置Spring和其他第三方依赖库
- 提供生产production-ready特性,例如健康检查,外部配置等
- 完全零代码生产和不需要XML配置
快速构建Maven项目
可以在https://start.spring.io进行快速生成一个SpringBoot的项目。
二、SpringBoot 核心原理
自动化配置、基于Configuration,EnableXX,Condition
spring-boot-starter:脚手架核心,快速整合第三方类库
AutoConfigurationImportSelector类的getAutoConfigurationEntry方法会先判断自动配置是否开启,如果开启,会去扫描所有配置在spring.factories里的name为EnableAutoConfiguration的类。
主要代码如下:
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;
}
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
//去扫描name为EnableAutoConfiguration的类
return EnableAutoConfiguration.class;
}
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
String factoryTypeName = factoryType.getName();
//根据factoryTypeName去load类
return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
Map<String, List<String>> result = cache.get(classLoader);
if (result != null) {
return result;
}
result = new HashMap<>();
try {
//FACTORIES_RESOURCE_LOCATION静态常量,值为META-INF/spring.factories,读取spring.factories文件,并进行处理
Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
...
条件化自动配置的注解
- @ConditionalOnBean
- @ConditionalOnClass
- @ConditionalOnJava
- @ConditionalOnMissingBean
- @ConditionalOnMissingClass
- @ConditionalOnProperty
- @ConditionalOnResource
- @ConditionalOnWebApplication
自定义starter
可以参看我的这篇博客:
https://www.cnblogs.com/javammc/p/13893698.html
为什么要约定大于配置
优势在于,开箱即用:
- Maven的目录结构:默认有resources文件夹存放配置文件。默认打包方式为jar
- 默认的配置文件:application.properties或application.yml
- 默认通过spring.profiles.active属性来决定运行环境时的配置文件
- EnableAutoConfiguration默认对于依赖的starter自动装配
- spring-boot-start-web中默认包含spring-mvc相关依赖以及内置的web容器,使得构建一个web应用更加简单。
书山有路勤为径,学海无涯苦作舟