概述
Spring Boot 是简化 Spring 应用开发的一个框架块,它整合了 Spring 的整个技术栈,提供了 J2EE 开发一站式解决方案。
它的目标是让你无需手动进行繁杂的配置或者只需要用到很少的配置就可以快速将你的项目运行起来。
核心功能
- 内置 Tomat,Jetty 和 Undertow servlet 容器,可以独立运行应用,无需打 war 包
- 提供一系列的 starter pom 来简化 maven 的依赖加载,可以将 starter pom 理解为实现某个功能所需的相关依赖的集合
- 自动配置 Spring,会根据项目类路径中的 jar 包,类来自动配置 Bean,从而减少手动配置,涵盖了大多数的开发场景,如果有需要可以自定义自动配置。
- 准生产的应用监控,如 指标,健康检查和外部化配置
- 无代码生成和 xml 配置,即 springboot 不是由代码生成来实现的,而是通过条件注解来实现,这是 Spring4.x 提供的新特性。
Spring Boot starter
Starter parent
spring-boot-starter-parent, 就是 pom 文件中的这段
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
它是启动 Spring Boot 应用的父依赖,包含了要使用的Java的默认版本,SpringBoot使用的依赖项的默认版本以及Maven插件的默认配置, 点击进去,可以看到它的几个重要配置如下,其中它默认读取资源目录下的 application 文件来进行应用配置,如果没有内容则使用默认的配置,支持 .properties, .yml 和 yaml 格式。
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
<artifactId>spring-boot-starter-parent</artifactId>
<packaging>pom</packaging>
<name>Spring Boot Starter Parent</name>
<description>Parent pom providing dependency and plugin management for applications
built with Maven</description>
<url>https://projects.spring.io/spring-boot/#/spring-boot-starter-parent</url>
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<resource.delimiter>@</resource.delimiter>
<maven.compiler.source>${java.version}</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
...
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/application*.yml</include>
<include>**/application*.yaml</include>
<include>**/application*.properties</include>
</includes>
</resource>
···
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<parameters>true</parameters>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>${start-class}</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
...
spring-boot-starter-parent 还继承了 spring-boot-dependencies,这个 pom文件才是真正定义了所有相关依赖及其默认版本:
<properties>
<activemq.version>5.15.12</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.79</appengine-sdk.version>
<artemis.version>2.10.1</artemis.version>
<aspectj.version>1.9.5</aspectj.version>
<assertj.version>3.13.2</assertj.version>
<atomikos.version>4.0.6</atomikos.version>
<awaitility.version>4.0.2</awaitility.version>
<bitronix.version>2.1.4</bitronix.version>
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
<byte-buddy.version>1.10.8</byte-buddy.version>
<caffeine.version>2.8.1</caffeine.version>
...
</properties>
Spring Boot 已经给定了大多数场景下依赖的默认版本,如果有需要你也可以在自己项目的pom文件中使用其他版本,比如 mysql-connector-java 的默认版本是 8.0.19,改为 8.0.18
<properties>
<java.version>1.8</java.version>
<mysql.version>8.0.18</mysql.version>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
Starter templates
Spring Boot starter 是包含启动特定功能所需的所有相关传递依赖项的集合,比如你想要创建一个 spring mvc 应用,如果按照传统方式,你需要添加所有相关依赖在 pom 文件中并给定版本,这样就很可能造成版本冲突,而 starter 已经为你提供了相关所有依赖,你只需要添加如下依赖即可:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Boot 提供了超过50种开箱即用的 starter pom,可以满足绝大多数的应用场景,比如关系型及非关系型数据库连接,应用监控,日志框架,模板渲染,web service支持等。
一些常用的 starter
名称 | 描述 |
---|---|
spring-boot-starter | 核心 starter, spring-context, spring-beans |
spring-boot-starter-actuator | 管理和监控应用 |
spring-boot-starter-web | web 开发支持,包含 tomcat 和 spring-mvc |
spring-boot-starter-test | 常用框架 Junit, Hamcrest,Mockito 支持 |
spring-boot-starter-aop | spring-aop, aspectjrt, aspectjweaver, 支持面向切面编程 |
spring-boot-starter-data-jpa | 支持 JPA,包含 spring-data-jpa, spring-orm 和 Hibernate |
spring-boot-starter-logging | logback-classic, jcl-over-slf4j, jul-to-slf4j, spring boot 默认框架 lockback |
spring-boot-starter-log4j | log4j2, log4j-slf4j-impl,Log4j 日志框架 |
spring-boot-starter-security | spring-security-web, spring-security-config,授权认证支持 |
Spring Boot 自动配置
Spring Boot 通过 @EnableAutoConfiguration 注解来开启自动配置,它会自动扫描类路径 jar 包,类来注册到 spring bean 中。
Spring Boot 自动配置的逻辑在 spring-boot-autoconfigure.jar 中,在这里可以查看 spring boot 做了哪些自动配置。
如 spring aop 的自动配置如下:
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Advice.class)
static class AspectJAutoProxyingConfiguration {
@Configuration(proxyBeanMethods = false)
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
matchIfMissing = false)
static class JdkDynamicAutoProxyConfiguration {
}
@Configuration(proxyBeanMethods = false)
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
static class CglibAutoProxyConfiguration {
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingClass("org.aspectj.weaver.Advice")
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
static class ClassProxyingConfiguration {
ClassProxyingConfiguration(BeanFactory beanFactory) {
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
}
}
}
spring boot是通过条件注解来实现自动配置的,注意上面的 Conditional 开头的注解,它们的含义是:
- @ConditionalOnProperty: 指定的属性是否有指定的值
- @ConditionalOnClass: 当类路径下有指定的类条件下
- @ConditionalOnMissingClass:当类路径下没有指定的类条件下
还有其他类似的注解,都是表示在什么条件下才生效的意思。
内置 Servlet 容器
Spring Boot 默认使用内置的 Tomcat 容器,无需复杂的基础设施配置就能独立运行一个 web 应用。 当然你可以选择使用其他的 servlet 容器比如 Jetty, 只需要在 pom 文件中排除 tomcat 依赖引入 jetty 依赖即可。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
启动 Spring Boot 应用
Spring Boot 应用通过一个名为 *Application.java 的入口类来启动
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
注意到上面的@SpringBootApplication 注解 ,其实包含了@Configuration, @EnableAutoConfiguration 和 @ComponentScan 这几个注解:
- @Configuration:表明一个类是配置类
- @EnableAutoConfiguration:开启自动配置
- @ComponentScan:把符合扫描规则的类装配到spring容器,对应 xml 中 的 <context:component-scan>
执行 main 方法会读取 application.properties 文件属性内容进行配置来启动应用程序。
application.properties
# Servlet 容器配置
# 端口
server.port=8080
# context
server.contextPath=/api
参考链接:
- https://spring.io/projects/spring-boot
- https://howtodoinjava.com/spring-boot-tutorials/