细粒度的自动配置
Spring的环境抽象
Spring的环境抽象是各种配置属性的一站式服务。它抽取了原始的属性,这样需要这些属性的bean就可以从Spring本身中获取。Spring环境会拉取多个属性源,包括:
-
JVM系统属性
-
操作系统环境变量
-
命令行参数
-
应用属性配置文件
它会将这些属性聚合到一个源中,通过这个源可以注入到Spring的bean中。Spring Boot自动配置的Bean都可以通过Spring 环境提取的属性进行配置。
当我们要希望底层的Servlet容器使用另外一个端口监听请求时,我们可以根据上述属性源进行更改。
- 应用属性配置文件:在application.properties更改,更习惯于重构为application.yaml文件
server:
port:9090
- 命令行参数启动应用时:
$ java - jar applicationName-0.0.5-SNAPSHOT.jar --server.port = 9090
- 操作系统变量
$ export SERVER_PORT = 9090
配置数据源
我们可以将数据源的属性配置添加到application.yaml中:
spring:
datasource:
url: jdbc:mysql://localhost/tacocloud
username: root
password:root
尽管我们需要将对应的JDBC驱动添加到构建文件中,但是我们不需要指定JDBC驱动类。Spring Boot会根据数据库URL的结构推算出来。
配置嵌入式服务器
我们如果将server.port设置为0,则服务器会任选一个可用的端口。
为了让底层容器处理Https请求。首先我们需要使用JDK的keytool命令行工具生成keystore:
$ keytool -keystore mykeys.jks -genkey -alias tomcat -keyyalg RSA
在application.yaml文件中声明配置:
server:
port: 8443
ssl:
key-store: file://path/to/mykeys.jks
key-store-password: root
key-password: root
我们将server.port设置为8443,这是在开发阶段HTTPS服务器的常用选择。server.ssl.key-store属性设置为我们所创建的keystore文件的路径。
配置日志
为了完全控制日志的配置,我们可以在类路径的根目录下(在src/main/resources中)创建一个logback.xml文件。
创建自己的配置属性
Spring Boot提供了@ConfigurantionProperties注解,将它放到Spring bean上之后,它就会为该bean中那些能够根据Spring环境注入值的属性赋值
@ConfigurationProperties(prefix = "taco.orders")
public class OrderController{
private int pageSize = 20;
···
...of(0,pageSize)...
@ConfigurationProperties注解的prefix属性设置成了taco.orders。这意味着设置pageSize的时候,我们需要使用名为taco.orders.pageSize的配置属性。我们可以在application.xml中更改该属性的值。
taco:
orders:
pageSize:10
同样的,如果在生产环境中需要快速更改,我们可以将该属性设置为环境变量。
$ export TACO_ORDERS_PAGESIZE = 10
由此可以消除硬编码带来的烦恼。
定义属性配置的持有者
@ConfigurationProperties通常会放到一种特定类型的bean中,这种bean的目的就是持有配置数据。这样的话,特定的配置细节就能从控制器和其他应用程序类中抽离出来,多个bean也能更容易地共享一些通用的配置。
@Component
@ConfigurationProperties(prefix = "taco.orders")
@Data
public class OrderProps {
private int pageSize = 20;
}
@Component 注解会让Spring的组件扫描功能自动发现并将其创建为Spring应用上下文中的bean。
对于控制器和其他应用程序类来说就是将属性持有者注入其中,就像repository一样,并使用。
我们应该将有关该领域的配置属性都归类于相关持有者中。我们可以将该属性持有者类像领域类一样进行校验
声明配置属性元数据
使用profile进行配置
profile是一种条件化的配置,在运行时,根据哪些profile处于激活状态,可以使用或者忽略不同的bean、配置类和配置属性。
定义特定profile的属性
在YAML配置中,特定profile的属性和非profile属性之间何以使用3个中划线进行分割,并且使用spring.profiles属性来命名profile。
taco:
orders:
pageSize:20
#设置启用的环境
spring:
profiles:
active: dev
---
#开发环境
spring:
config:
activate:
on-profile: dev
lesson: SpringBoot
server:
port: 80
enterprise:
name: itcast
age: 16
tel: 6696666
subject:
- Java
- 前端
- 大数据
---
#生产
spring:
config:
activate:
on-profile: pro
server:
port: 81
lesson: SpringBoot
enterprise:
name: itcast
age: 16
tel: 6696666
subject:
- Java
- 前端
- 大数据
没有指定profile的就是代表它们是默认的,通用的,当然当启动某一profiles时,后者可以覆盖前者。
激活profile
我们可以这样设置
#设置启用的环境
spring:
profiles:
active: dev
可以使用环境变量设置处于激活状态的profile
$ export SPRING_PROFILES_ACTIVE = prod
也可以使用命令行参数
% java -jar taco-cloud.jar --spring.profiles.active = prod
我们可以设置多个激活的profile。如果使用环境变量,用逗号分隔的列表:
% export SPRING_PROFILES_ACTIVE = prod,audit,ha
在YAML中
spring:
profiles:
active:
- prod
- audit
- ha
使用profile条件化创建bean
假设我们希望某些bean仅在特定profile激活的情况下才需要创建,@profile注解可以将某些bean设置为仅适用于给定的profile。
@Bean
@Profile("dev")
public String test(){
}
多个环境
@Bean
@Profile("dev","qa")
public String test(){
}
不在某个环境创建
@Bean
@Profile("!dev")
public String test(){
}
只要dev不激活,就创建该bean
我们还可以在带有@Configuration注解的类上使用profile
@Profile("!prod","!qa")
@Configuration
public class TestConfig {
...
}