Spring必知必会的技术

Spring 必知必会的技术

参数配置

常用的有两种方式:@Value 和@ConfigurationProperties

Feature @ConfigurationProperties @Value
Relaxed binding Yes Limited (see note below)
Meta-data support Yes No
SpEL evaluation No Yes

@Value

首先需要在配置类上增加@Configuration

带默认值的

1
2
@Value("${kafka.producer.retry:1}")
private int retry;

使用 Spring Expression Language (SpEL)

1
2
@Value("#{'${actuator.send.business.type:eims,item}'.split(',')}")
List<String> specifyType;

@ConfigurationProperties

该方式可以将相应的配置封装在具体类内,对代码组织和封装友好,推进使用这种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@ConfigurationProperties(prefix = "my.server")
public class MyServerProperties {
private String name="test";
@NotNull
private String bootstrapServers;
private Host host;
// getters/setters ...
// 嵌入式结构
public static class Host {
private String ip;
private int port;
// getters/setters ...
}
}
1
2
3
4
5
6
my.server:
name: test
bootstrap_servers: xxxxx:9092
host:
ip: xxx
port: 8081

扩展:

为了让 spring 容器可以识别该配置类,有多种方式,这里我推荐在启动类上添加注解@ConfigurationPropertiesScan({"top.trumandu.config"})

配置参数

Spring(relaxed binding )使用一些宽松的绑定属性规则。因此,以下变体都将绑定到 hostName 属性上:

1
2
3
4
5
mail.hostName=localhost
mail.hostname=localhost
mail.host_name=localhost
mail.host-name=localhost
mail.HOST_NAME=localhost

为了让 ide 可以识别我们自定义的配置文件,可以添加 spring-boot-configuration-processor,这样就可以自动生成additional-spring-configuration-metadata.json, 进而进行提示。

配置文件优先级

classpath root > classpath/config > current directory > current directory/config/ > current directory/../config

日志

默认使用 Logback,通常我们只用如下配置即可快速使用.

1
2
3
4
5
logging:
level:
root: "warn"
org.springframework.web: "debug"
org.hibernate: "error"

当无法满足一些日志场景时,Logback 扩展可以通过在src/main/resources 创建logback-spring.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--<jmxConfigurator/> -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{ISO8601} %-5level [%thread] %logger{0}: %msg%n
</pattern>
</encoder>
</appender>

<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
%d{ISO8601} %-5level [%thread] %logger{0}: %msg%n
</pattern>
</encoder>
</appender>

<appender name="ERROR_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
%d{ISO8601} %-5level [%thread] %logger{0}: %msg%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>error</level>
</filter>
</appender>

<logger name="top.trumandu" level="info" />
<logger name="org.apache" level="error" />
<logger name="org.I0Itec.zkclient" level="error" />
<root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</configuration>

Spring 容器启动以后运行任务

可以实现ApplicationRunnerCommandLineRunner 接口

1
2
3
4
5
6
7
8
@Component
public class MyCommandLineRunner implements CommandLineRunner {

@Override
public void run(String... args) {
// Do something...
}
}

优先级可以通过@Ordered 实现

说明

如果你对这个系列感兴趣,可以看我在写的一本电子书 ​:《Better Javaer》

参考

  1. 11 个 Spring 最常用的功能扩展点,手摸手实战