本来在controller文件中是:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16@RestController
public class HelloController {
@Valid("${minMoney}")
private BigDecimal minValue;
@Valid("${maxMoney}")
private BigDecimal maxValue;
@Valid("${description}")
private String description;
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String say() {
return ...
}
对应的yml配置是:1
2
3
4
5
6
7
8
9server:
port: 8081
servlet:
context-path: /luckymoney
minMoney: 0.01
maxMoney: 9999
description: minvalue would be $1
如果配置中的字段越来越多,那么在controller中对应配置字段的类属性也越来越多,重复写@Valid
很多: 为了避免这种问题, 更好的方式是把现在controller中的类属性全部放在一个类中,这样配置的时候只用配置这个类,只用写一次注解,不用重复写多次@Valid
.
改配置为:1
2
3
4
5
6
7
8
9server:
port: 8081
servlet:
context-path: /luckymoney
limit:
minMoney: 0.01
maxMoney: 9999
description: minvalue would be $1
在HelloController
同级目录下创建文件LimitConfig
,注意注解@ConfigurationProperties
的参数prefix
,要和配置那个结构体名称对应起来1
2
3
4
5
6
7
8
9
10
11@ConfigurationProperties(prefix = "limit")
public class LimitConfig {
private BigDecimal minMoney;
private BigDecimal maxMoney;
private String description;
// getters and setters
}
此时controller为:1
2
3
4
5
6
7
8
9
10@RestController
public class HelloController {
@Autowired
private LimitConfig limitConfig;
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String say() {
return limitConfig.getDescription();
}
也就是@Autowired
都是用来注解类的(其实最多是用来装配POJO的), 此时运行会报错Could not autowire. No beans of 'LimitConfig' type found.
这是因为spring容器并不知道这个类是什么东西,要用@Component
告诉容器可以自动装配这个类,从而把这个POJO变成bean:1
2
3
4
5
6
7
8
9
10
11
12@Component
@ConfigurationProperties(prefix = "limit")
public class LimitConfig {
private BigDecimal minMoney;
private BigDecimal maxMoney;
private String description;
// getters and setters
}
仔细一想,autowired实际上是完成了把POJO变成bean的第二步。bean的来源都是两步:
- 定义好POJO;
- dependency injection;
第二步如果手动写,我记得是要用另一个config类注解@ComponentScan
配合POJO类的@Component
, 这里@Autowired
就自动装配自动扫描存在的component从而注入得到bean。