? ? ? ? 从百度上获得的概念:Spring Boot是一个基于Spring框架的快速开发应用程序的工具。它简化了Spring应用程序的创建和开发过程,使开发人员能够更快速地创建独立的、生产就绪的Spring应用程序。
? ? ? ? 说点更容易理解的:SpringBoot框架就是基于Spring框架做了许多衍生,例如基于Spring官方注解做的衍生(例如由@Condition注解衍生出的@ConditionOn...注解);基于Spring框架编写的自动配置类(...AutoConfiguration);这些衍生(扩展)很大程度上减少了开发人员需要进行手动配置的复杂程度,提供了自动配置和快速开发的功能,从而让开发人员可以更加专注于业务逻辑。
? ? ? ? 除此之外,两者在特性上也稍有不同,Spring框架的特性提供了创建对象、依赖注入、AOP编程等功能,而SpringBoot框架的特性更侧重于依赖管理、自动配置及覆盖、项目打包等功能。
? ? ? ? 如果不涉及SpringBoot框架,当我们在Spring项目中添加依赖时,我们需要自己手动配置该依赖的版本以确保它能够和其他依赖协调(兼容),例如Spring框架的核心依赖项为spring-context,这个依赖项会间接依赖spring-core;SpringMVC框架的核心依赖项为spring-webmvc,它也间接地依赖了spring-core,那么当spring-context和spring-webmvc这两个依赖的版本不一致时,其依赖的spring-core版本可能也是不一样的,这个时候项目启动就会出现异常。
? ? ? ? SpringBoot的依赖管理就很好的解决了上面这个问题,通过引入springboot父级依赖,再添加spring-boot-starter依赖就可以管理其他至少16个spring依赖项,包括了spring-core-xxx;spring-context-xxx;spring-bean-xxx等依赖都进行了协调
? ? ? ? 说点更容易理解的,相当于SpringBoot帮助我们列了一个清单,这些清单上面记着许多的依赖项,springboot会根据自己的依赖版本选择合适的清单上的依赖项版本来达到项目中所有依赖相兼容的结果,所以我们会发现在导入以spring-boot-starter开头的依赖项时,我们并不需要去指定它的版本maven也能够刷新成功。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--springboot父级依赖-->
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.5.9</version>
</parent>
<groupId>com.cola</groupId>
<artifactId>mockmvcTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!--spring-boot-starter依赖,不需要指定依赖版本,在父级中已经进行指定-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
????????所谓自动配置就是springboot可以根据当前项目的各种环境,帮助我们实现自动创建它认为你所需要的bean的过程
添加spring-boot-stater-web → springboot自动配置tomcat容器,运行web服务器
添加spring-boot-starter-jdbc → 我们只需要在配置文件中提供datasource所需属性,springboot自动配置datasource,连接数据库
? ? ? ?springboot能够实现自动配置的直接原因是因为?springboot基于spring的扩展功能,在4.X别写了一堆的自动配置类(这些配置类名字都为“xxx
AutoConfiguration”
),只要存在spring-boot-starter
的依赖资源,一定会有这些自动配置(大约有131个),这些自动配置被保存在下图路径中:
自动配置是如何工作的 :
? ? ? ? springboot能够实现自动配置除了因为它自己编写的自动配置类清单之外,还依赖于项目主启动类上的@SpringBootApplication注解,这个注解是一个组合注解,它由@SpringBootConfiguration、@ComponentScan、@EnableAutoConfiguration三个注解组合而成
?????????在项目启动后,spring会提供一个SpringFactoriesLoader加载器,这个加载器就会通过@EnableAutoConfiguration加载spring.factories文件,从而获取所有的自动配置类的全路径
满足上方条件后,所有的自动配置类一定都会被执行吗?
? ? ? ? 答案显然是否定的。虽然启动类可以导入众多的自动配置类,但是自动配置类最终是否加载,取决于每个配置类上的配置条件注解是否成立。
????????在Spring4.X,出现了一个条件注解@Conditional,SpringBoot就是基于这个条件注解,创建了很多的衍生注解,具体的编写了条件规则。
@ConditionOnClass:指定类如果存在于当前环境则加载对应类
@ConditionOnMissingClass?:指定类如果不存在于当前环境则加载对应类
? ? ? ? 以上两个注解的条件逻辑是相反的,都是类和方法的注解,如果作用在类上,一般也是配置类,这两个注解会根据条件属性,判断某个、某几个指定的类是否存在于当前的环境
存在或不存在都是满足条件的前提,对应的类或者方法才会选择加载或者不加载
????????例如在数据库配置中的DataSource类上方就存在一个类的条件注解,当存在DataSource这个类时该自动配置类才会被加载
@ConditionalOnBean(value={Bean02.class})
@ConditionalOnMissingBean(value={Bean01.class})
? ? ? ? 判断指定的Bean对象在容器内是否存在,存在或不存在都是满足条件的前提,对应的类或者方法才会选择加载或者不加载
例如:
指定实体类
@Component
public class Bean02 {
public Bean02() {
System.out.println("当前容器加载了Bean02");
}
}
指定配置类
@Configuration
//根据条件配置类和实体类所在包路径进行扫描
@ComponentScan(basePackages ={"com.cola.spring.boot.bean",
"com.cola.spring.boot.condition"
} )
public class Demo01ConfigReplaceXML {
public Demo01ConfigReplaceXML() {
System.out.println("当前容器加载了Demo01Config配置类");
}
}
指定条件配置类
@Configuration
@ConditionalOnBean(value = {Bean02.class})
//value属性指定的bean实例如果在容器中不存在,则满足条件
public class ConditionalDemo02Config {
public ConditionalDemo02Config() {
System.out.println("条件成立,ConditionalDemo02Config配置类被加载了");
}
}
读取指定配置类
@Test
public void configLoad() {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(Demo01ConfigReplaceXML.class);
}
输出结果:
?????????当前容器加载了Demo01Config配置类
? ? ? ? ?当前容器加载了Bean02
? ? ? ? ?条件成立,ConditionalDemo02Config配置类被加载了
@ConditionOnProperty
@ConditionOnMissingProperty
? ? ? ? 这两个注解都允许springBoot读取xxx.properties配置文件,配合配置类作用在配置类或者配置类的方法,决定类或者方法到底加载不加载,它可以设置以下几个属性
- prefix: 表示key值的前缀
- value: 拼接prefix组合一个字符串,去定位key(例如cola.demo.name这就是一个key)
- havingValue: 判断依据是否存在prefix.value的key对应的值
- matchIfMissing:如果没有在配置文件中配置prefix+value指定key,则默认成立;如果key存在,则正常比较值是否相同?
? ? ? ? 通过SpringBoot的Maven插件,我们可以将项目源代码打成可以运行的Fat jar(就是我们俗称的jar包),通常在我们使用Spring初始化工具新建项目时,在pom文件中都会有一个用于将项目打包的build-plugin依赖
?但是目前spring已经无法使用jdk8版本创建SpringBoot,我们需要先创建一个普通Maven项目再加入必要的SpringBoot依赖和主启动类来让项目成为一个SpringBoot项目,因此,上图的build依赖项也需要我们自己添加在pom文件中,如下:
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.9</version>
<configuration>
<executable>true</executable>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<attach>false</attach>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
添加完成后,如果代码运行没有错误,我们可以借助idea工具进行项目打包
打包完成后, 在对应的目录下就会出现xxx.jar文件,通过以下命令即可执行
java -jar jar包路径