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