2. 多个配置信息的情形
这里再引申一个问题,随着业务复杂度的增加,一个项目中可能会有越来越多的微服务,某个模块可能需要调用多个微服务获取不同的信息,那么就需要在配置文件中配置多个微服务的地址。可是,在需要调用这些微服务的代码中,如果这样一个个去使用 @Value
注解引入相应的微服务地址的话,太过于繁琐,也不科学。
所以,在实际项目中,业务繁琐,逻辑复杂的情况下,需要考虑封装一个或多个配置类。举个例子:假如在当前服务中,某个业务需要同时调用订单微服务、用户微服务和购物车微服务,分别获取订单、用户和购物车相关信息,然后对这些信息做一定的逻辑处理。那么在配置文件中,我们需要将这些微服务的地址都配置好:
# 配置多个微服务的地址
url:
# 订单微服务的地址
orderUrl: http://localhost:8002
# 用户微服务的地址
userUrl: http://localhost:8003
# 购物车微服务的地址
shoppingUrl: http://localhost:8004
也许实际业务中,远远不止这三个微服务,甚至十几个都有可能。对于这种情况,我们可以先定义一个 MicroServiceUrl
类来专门保存微服务的 url,如下:
@Component
@ConfigurationProperties(prefix = "url")
public class MicroServiceUrl {
private String orderUrl;
private String userUrl;
private String shoppingUrl;
// 省去get和set方法
}
细心的朋友应该可以看到,使用 @ConfigurationProperties
注解并且使用 prefix 来指定一个前缀,然后该类中的属性名就是配置中去掉前缀后的名字,一一对应即可。即:前缀名 + 属性名就是配置文件中定义的 key。同时,该类上面需要加上 @Component
注解,把该类作为组件放到Spring容器中,让 Spring 去管理,我们使用的时候直接注入即可。
需要注意的是,使用 @ConfigurationProperties
注解需要导入它的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
OK,到此为止,我们将配置写好了,接下来写个 Controller 来测试一下。此时,不需要在代码中一个个引入这些微服务的 url 了,直接通过 @Resource
注解将刚刚写好配置类注入进来即可使用了,非常方便。如下:
@RestController
@RequestMapping("/test")
public class TestController {
private static final Logger LOGGER = LoggerFactory.getLogger(TestController.class);
@Resource
private MicroServiceUrl microServiceUrl;
@RequestMapping("/config")
public String testConfig() {
LOGGER.info("=====获取的订单服务地址为:{}", microServiceUrl.getOrderUrl());
LOGGER.info("=====获取的用户服务地址为:{}", microServiceUrl.getUserUrl());
LOGGER.info("=====获取的购物车服务地址为:{}", microServiceUrl.getShoppingUrl());
return "success";
}
}
再次启动项目,请求一下可以看到,控制台打印出如下信息,说明配置文件生效,同时正确获取配置文件内容:
=====获取的订单服务地址为:http://localhost:8002
=====获取的订单服务地址为:http://localhost:8002
=====获取的用户服务地址为:http://localhost:8003
=====获取的购物车服务地址为:http://localhost:8004