本来在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。