运用Spring Boot
在start.spring.io
可以直接下载Spring Boot项目
|
| pom.xml
|
|
\---src
+---main
| +---java
| | \---com
| | \---zdx
| | \---readinglist
| | ReadingListApplication.java
| |
| \---resources
| | application.properties
| |
| +---static
| \---templates
\---test
\---java
\---com
\---zdx
\---readinglist
ReadingListApplicationTests.java
查看初始化Spring Boot 新项目
- 目录结构遵循传统Maven项目的布局
- 主要的应用代码位于
src/main/java
- 资源文件位于
src/main/resources
- 测试代码在
src/test/java
- 如果有测试资源的话,应在
src/test/resources
主要的文件:
ReadingListApplication.java
应用程序的启动引导类(bootstrap class),也是主要的Spring配置类。application.properties
用于配置应用程序和Spring Boot的属性。ReadingListApplicationTests.java
一个基本的集成测试类。
启动引导Spring
ReadingListApplication.java
在Spring中有两个作用:
- 配置
- 启动引导
虽然Spring Boot的自动配置免除了很多Spring配置,但你还需要进行少量配置来启用自动配置
默认情况下只有一行配置代码:
package com.zdx.readinglist;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
//开启组件扫描和自动配置
public class ReadingListApplication {
public static void main(String[] args) {
//负责启动引导应用程序
SpringApplication.run(ReadingListApplication.class, args);
}
}
@SpringBootApplication
开启了Spring的组件扫描和Spring Boot的自动配置功能,但实际上@SpringBootApplication
将三个有用的注解组合在了一起:@Configuration
标明该类使用Spring基于Java的配置...@ComponentScan
启用组件扫描,这样自定义的Web控制器类和其他组件才会被自动发现并注册为Spring应用程序上下文里面的Bean@EnableAutoConfiguration
也被称为@Abracadabra
:就是这一行配置开启了Spring Boot自动配置
配置应用程序的属性
默认生成的application.properties
文件是一个空文件
如果application.properties
存在就会被加载,无需指定
application.properties
使用例子:
server.port=8000
加上这一行,嵌入式Tomcat的监听端口就变成了8000
Spring Boot 项目构建过程解析
Spring Boot为Gradle 和 Maven提供了构建插件 以便辅助构建Spring Boot项目...
选择Maven会替你生成一个pom.xml文件,其中使用了Spring Boot的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>
<!--从 spring-boot-starter parent继承版本号-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zdx</groupId>
<artifactId>readinglist</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Reading List</name>
<description>Reading List Demo</description>
<properties>
<java.version>1.8</java.version>
</properties>
<!-- 起步依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!--运用Spring Boot插件-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
构建插件的主要功能是把项目打包成一个可执行的超级JAR(uber-JAR),包括把应用程序的所有依赖打入JAR文件内,并为JAR添加一个描述文件,其中的内容能让你用java -jar来运行应用程序。
除了构建插件,还将spring-boot-starter-parent作为上一级,这样一来就能利用Maven的依赖管理功能继承很多常用库的依赖版本,在你声明依赖时就不用再去指定版本号了。请注意,这个pom.xml里的
<dependency>
都没有指定版本
起步依赖
首先,假设不存在起步依赖,用Spring MVC的话,我们得晓得以下几点:
- 需要哪个Spring依赖
- Thymeleaf的Group和Artifact ID
- 用哪个版本的Spring Data JPA
- 兼容问题
而这只不过是开发一个Spring Web应用程序,使用Thymeleaf
视图,通过JPA
进行数据持久化.但是在敲代码前,我们需要明白,要支持我们的项目,需要往POM.XML中加入哪些东西.
可能有以下几个:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>2.1.7.RELEASE</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.1.7.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>5.1.6.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
这段依赖列表不错,应该能正常工作,但任何得知?在一行代码都没写的情况下,我们离开始构建还有很长的路要走
- 让我们退一步再想想,我们要做什么。我们要构建一个拥有如下功能的应用程序。
- 这是一个Web应用程序。
- 它用了Thymeleaf
- 它通过Spring Data JPA在关系型数据库里持久化数据
如果我们只在构建文件里指定这些功能,让构建过程自己搞明白我们要什么东西,岂不是更简单?这正是Spring Boot起步依赖的功能
覆盖起步依赖引入的传递依赖
以Spring Boot的Web起步依赖为例,它传递依赖了Jackson JSON
库。如果你正在构建一个生产或消费JSON资源表述的REST服务,那它会很有用。但是,要构建传统的面向人类用户的Web应用程序,你可能用不上Jackson
。虽然把它加进来也不会有什么坏处,但排除掉它的传递依赖,可以为你的项目瘦身.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
</dependency>
另一方面,也许项目需要Jackson,但你需要用另一个版本的Jackson来进行构建,而不是Web起步依赖里的那个。假设Web起步依赖引用了Jackson 2.3.4,但你需要使用2.4.3。在Maven里,你可以直接在pom.xml中表达诉求,就像这样:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>
使用自动配置
在向应用程序加入Spring Boot时,有个名为spring-boot-autoconfigure的JAR文件,其中包含了很多配置类。每个配置类都在应用程序的Classpath里,都有机会为应用程序的配置添砖加瓦。这些配置类里有用于Thymeleaf的配置,有用于Spring Data JPA的配置,有用于Spiring MVC的配置,还有很多其他东西的配置,你可以自己选择是否在Spring应用程序里使用它们。
所有这些配置如此与众不同,原因在于它们利用了Spring的条件化配置,这是Spring 4.0引入的新特性。条件化配置允许配置存在于应用程序中,但在满足某些特定条件之前都忽略这个配置。
在Spring里可以很方便地编写你自己的条件,你所要做的就是实现Condition接口,覆盖它的matches()方法。举例来说,下面这个简单的条件类只有在Classpath里存在JdbcTemplate时才会生效...
public class JdbcTemplateCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
try {
context.getClassLoader().loadClass("org.springframework.jdbc.core.JdbcTemplate");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}
而当你用Java来声明Bean的时候,可以使用这个自定义条件类:
@Conditional(JdbcTemplateCondition.class)
public MyService myService() {
...
}
在这个例子里,只有当JdbcTemplateCondition类的条件成立时才会创建MyService这个Bean。也就是说MyService Bean创建的条件是Classpath里有JdbcTemplate。否则,这个Bean的声明就会被忽略掉。
这些配置类构成了Spring Boot的自动配置。 Spring Boot运用条件化配置的方法是,定义多个特殊的条件化注解,并将它们用到配置类上