3.2.1 自动配置微调
如上所说,有 300 多个属性可以用来微调 Spring Boot 应用程序里的 Bean。附录 C 有一个详尽的列表。此处无法逐一描述它们的细节,因此我们就通过几个例子来了解一些 Spring Boot 暴露的实用属性。
1. 禁用模板缓存
如果阅读列表应用程序经过了几番修改,你一定已经注意到了,除非重启应用程序,否则对 Thymeleaf 模板的变更是不会生效的。这是因为 Thymeleaf 模板默认缓存。这有助于改善应用程序的性能,因为模板只需编译一次,但在开发过程中就不能实时看到变更的效果了。
将 spring.thymeleaf.cache
设置为 false
就能禁用 Thymeleaf 模板缓存。在命令行里运行应用程序时,将其设置为命令行参数即可:
$ java -jar readinglist-0.0.1-SNAPSHOT.jar --spring.thymeleaf.cache=false
或者,如果你希望每次运行时都禁用缓存,可以创建一个 application.yml,包含以下内容:
spring:
thymeleaf:
cache: false
你一定要确保这个文件不会发布到生产环境,否则生产环境里的应用程序就无法享受模板缓存带来的性能提升了。
作为开发者,在修改模板时始终关闭缓存实在太方便了。为此,可以通过环境变量来禁用 Thymeleaf 缓存:
$ export spring_thymeleaf_cache=false
此处使用 Thymeleaf 作为应用程序的视图,Spring Boot 支持的其他模板也能关闭模板缓存,设置这些属性就好了:
spring.freemarker.cache
(Freemarker)spring.groovy.template.cache
(Groovy 模板)spring.velocity.cache
(Velocity)
默认情况下,这些属性都为 true
,也就是开启缓存。将它们设置为 false
即可禁用缓存。
2. 配置嵌入式服务器
从命令行(或者 Spring Tool Suite)运行 Spring Boot 应用程序时,应用程序会启动一个嵌入式的服务器(默认是 Tomcat),监听 8080 端口。大部分情况下这样挺好,但同时运行多个应用程序可能会有问题。要是所有应用程序都试着让 Tomcat 服务器监听同一个端口,在启动第二个应用程序时就会有冲突。
无论出于什么原因,让服务器监听不同的端口,你所要做的就是设置 server.port
属性。要是只改一次,可以用命令行参数:
$ java -jar readinglist-0.0.1-SNAPSHOT.jar --server.port=8000
但如果希望端口变更时间更长一点,可以在其他支持的配置位置上设置 server.port
。例如,把它放在应用程序 Classpath 根目录的 application.yml 文件里:
server:
port: 8000
除了服务器的端口,你还可能希望服务器提供 HTTPS 服务。为此,第一步就是用 JDK 的 keytool
工具来创建一个密钥存储(keystore):
$ keytool -keystore mykeys.jks -genkey -alias tomcat -keyalg RSA
该工具会询问几个与名字和组织相关的问题,大部分都无关紧要。但在被问到密码时,一定要记住你的选择。在本例中,我选择 letmein 作为密码。
现在只需要设置几个属性就能开启嵌入式服务器的 HTTPS 服务了。可以把它们都配置在命令行里,但这样太不方便了。可以把它们放在 application.properties 或 application.yml 里。在 application.yml 中,它们可能是这样的:
server:
port: 8443
ssl:
key-store: file:///path/to/mykeys.jks
key-store-password: letmein
key-password: letmein
此处的 server.port
设置为 8443,开发环境的 HTTPS 服务器大多会选这个端口。 server.ssl.key-store
属性指向密钥存储文件的存放路径。这里用了一个 file://开头的 URL,从文件系统里加载该文件。你也可以把它打包在应用程序的 JAR 文件里,用 classpath: URL
来引用它。 server.ssl.key-store-password
和 server.ssl.key-password
设置为创建该文件时给定的密码。
有了这些属性,应用程序就能在 8443 端口上监听 HTTPS 请求了。(根据你所用的浏览器,可能会出现警告框提示该服务器无法验证其身份。在开发时,访问的是 localhost,这没什么好担心的。)
3. 配置日志
大多数应用程序都提供了某种形式的日志。即使你的应用程序不会直接记录日志,你所用的库也会记录它们的活动。
默认情况下,Spring Boot 会用 Logback( http://logback.qos.ch )来记录日志,并用 INFO
级别输出到控制台。在运行应用程序和其他例子时,你应该已经看到很多 INFO
级别的日志了。
用其他日志实现替换 Logback
一般来说,你不需要切换日志实现;Logback 能很好地满足你的需要。但是,如果决定使用 Log4j 或者 Log4j2,那么你只需要修改依赖,引入对应该日志实现的起步依赖,同时排除掉 Logback。
以 Maven 为例,应排除掉根起步依赖传递引入的默认日志起步依赖,这样就能排除 Logback 了:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
在 Gradle 里,在 configurations
下排除该起步依赖是最简单的办法:
configurations {
all*.exclude group:'org.springframework.boot',
module:'spring-boot-starter-logging'
}
排除默认日志的起步依赖后,就可以引入你想用的日志实现的起步依赖了。在 Maven 里可以这样添加 Log4j:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
在 Gradle 里可以这样添加 Log4j:
compile("org.springframework.boot:spring-boot-starter-log4j")
如果你想用 Log4j2,可以把 spring-boot-starter-log4j 改成 spring-boot-starter-log4j2。
要完全掌握日志配置,可以在 Classpath 的根目录(src/main/resources)里创建 logback.xml 文件。下面是一个 logback.xml 的简单例子:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<logger name="root" level="INFO"/>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
除了日志格式之外,这个 Logback 配置和不加 logback.xml 文件的默认配置差不多。但是,通过编辑 logback.xml,你可以完全掌控应用程序的日志文件。哪些配置应该放进 logback.xml 这个话题不在本书的讨论范围内,请参考 Logback 的文档以了解更多信息。
即使如此,你对日志配置最常做的改动就是修改日志级别和指定日志输出的文件。使用了 Spring Boot 的配置属性后,你可以在不创建 logback.xml 文件的情况下修改那些配置。
要设置日志级别,你可以创建以 logging.level
开头的属性,后面是要日志名称。如果根日志级别要设置为 WARN
,但 Spring Security 的日志要用 DEBUG
级别,可以在 application.yml 里加入以下内容:
logging:
level:
root: WARN
org:
springframework:
security: DEBUG
另外,你也可以把 Spring Security 的包名写成一行:
logging:
level:
root: WARN
org.springframework.security: DEBUG
现在,假设你想把日志写到位于/var/logs/目录里的 BookWorm.log 文件里。使用 logging.path
和 loggin.file
属性就行了:
logging:
path: /var/logs/
file: BookWorm.log
level:
root: WARN
org:
springframework:
security: DEBUG
假设应用程序有/var/logs/的写权限,日志就能被写入/var/logs/BookWorm.log。默认情况下,日志文件的大小达到 10MB 时会切分一次。
与之类似,这些属性也能在 application.properties 里设置:
logging.path=/var/logs/
logging.file=BookWorm.log
logging.level.root=WARN
logging.level.root.org.springframework.security=DEBUG
如果你还是想要完全掌控日志配置,但是又不想用 logback.xml 作为 Logback 配置的名字,可以通过 logging.config
属性指定自定义的名字:
logging:
config:
classpath:logging-config.xml
虽然一般并不需要改变配置文件的名字,但是如果你想针对不同运行时 Profile 使用不同的日志配置(见 3.2.3 节),这个功能会很有用。
4. 配置数据源
此时,我们还在开发阅读列表应用程序,嵌入式的 H2 数据库能很好地满足我们的需要。可是一旦要投放到生产环境,我们可能要考虑更持久的数据库解决方案。
虽然你可以显式配置自己的 DataSource
Bean,但通常并不用这么做,只需简单地通过属性配置数据库的 URL 和身份信息就可以了。举例来说,如果你用的是 MySQL 数据库,你的 application.yml 文件看起来可能是这样的:
spring:
datasource:
url: jdbc:mysql://localhost/readinglist
username: dbuser
password: dbpass
通常你都无需指定 JDBC 驱动,Spring Boot 会根据数据库 URL 识别出需要的驱动,但如果识别出问题了,你还可以设置 spring.datasource.driver-class-name
属性:
spring:
datasource:
url: jdbc:mysql://localhost/readinglist
username: dbuser
password: dbpass
driver-class-name: com.mysql.jdbc.Driver
在自动配置 DataSource
Bean 的时候,Spring Boot 会使用这里的连接数据。 DataSource
Bean 是一个连接池,如果 Classpath 里有 Tomcat 的连接池 DataSource
,那么就会使用这个连接池;否则,Spring Boot 会在 Classpath 里查找以下连接池:
HikariCP
Commons DBCP
Commons DBCP 2
这里列出的只是自动配置支持的连接池,你还可以自己配置 DataSource
Bean,使用你喜欢的各种连接池。
你也可以设置 spring.datasource.jndi-name
属性,从 JNDI 里查找 DataSource
:
spring:
datasource:
jndi-name: java:/comp/env/jdbc/readingListDS
一旦设置了 spring.datasource.jndi-name
属性,其他数据源连接属性都会被忽略,除非没有设置别的数据源连接属性。
有很多影响 Spring Boot 自动配置组件的方法,只需设置一两个属性即可。但这种配置外置的方法并不局限于 Spring Boot 配置的 Bean。让我们看看如何使用这种属性配置机制来微调自己的应用程序组件。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论