SpringBoot-5

Spring Boot 的项目属性配置

在项目中很多时候需要用到一些配置的信息,这些信息可能在测试环境和生产环境下会有不同的配置,后面根据实际业务情况有可能还会做修改,针对这种情况不能将这些配置在代码中写死,最好就是写到配置文件中。

比如可以把这些信息写到 application.yml 文件中。

在具体应用中实际上 application.properties 和 application.yml 都可以使用,并允许同时使用。如果同时进行配置,且配置冲突,则 properties 优先于 yml

1、少量配置信息的情形

例如在微服务架构中,最常见的就是某个服务需要调用其他服务来获取其提供的相关信息,那么在该服务的配置文件中需要配置被调用的服务地址,比如在当前服务里需要调用订单微服务获取订单相关的信息,假设订单服务的端口号是 8002,那可以做配置:

yml 复制代码
server:
   port: 8001
# 配置微服务的地址
url: # 自定义的订单微服务的地址。不是系统预定义的配置,所以不会出现任何提示
orderUrl: http://localhost:8002

然后在业务代码中如何获取到这个配置的订单服务地址呢?可以使用@Value 注解来解决。在对应的类中加上一个属性,在属性上使用@Value 注解即可获取到配置文件中的配置信息

java 复制代码
@RestController
@RequestMapping("/test")
public class ConfigController {
    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigController.class);
    @Value("${url.orderUrl}") 
//其中的内容为 SpEL 即 Spring 表达式语言,可以获取配置文件中 url.orderUrl的值
    private String orderUrl;
    @RequestMapping("/config")
    public String testConfig() {
        LOGGER.info("=====获取的订单服务地址为:{}", orderUrl);
        return "success";
    }
}

@Value 注解上通过${key}即可获取配置文件中和 key 对应的 value 值。启动一下项目在浏览器中输入localhost:8080/test/config 请求服务后,可以看到控制台会打印出订单服务的地址:

=====获取的订单服务地址为:http://localhost:8002

说明成功获取到了配置文件中的订单微服务地址,在实际项目中也是这么用的,后面如果因为服务器部署的原因,需要修改某个服务的地址,那么只要在配置文件中修改即可。

2、多个配置信息的情形

这里再引申一个问题,随着业务复杂度的增加,一个项目中可能会有越来越多的微服务,某个模块可能需要调用多个微服务获取不同的信息,那么就需要在配置文件中配置多个微服务的地址。可是在需要调用这些微服务的代码中,如果这样一个个去使用@Value 注解引入相应的微服务地址的话,太过于繁琐,也不科学。所以在实际项目中,业务繁琐,逻辑复杂的情况下,需要考虑封装一个或多个配置类。

举个例子:假如在当前服务中,某个业务需要同时调用订单微服务、用户微服务和购物车微服务,分别获取订单、用户和购物车相关信息,然后对这些信息做一定的逻辑处理。那么在配置文件中,需要将这些微服务的地址都配置好

yml 复制代码
url: #配置多个微服务的地址
    orderUrl: http://localhost:8002 
#订单微服务的地址,注意 key 值不能重复,但是允许 key 对应的值是集合类型
    userUrl: http://localhost:8003 #用户微服务的地址
    shoppingUrl: http://localhost:8004 #购物车微服务的地址

实际上在实际业务中,可能远远不止这三个微服务,甚至十几个都有可能。对于这种情况可以先定义一个MicroServiceUrl 类来专门保存微服务的 url。如果配置较多,可以自定义一个专门用于存储配置参数的类

java 复制代码
@Component //定义受管 bean,否则 Spring 无法注入配置参数值
@ConfigurationProperties(prefix = "url") //用于读取配置信息,声明配置以 url 开头。需要解析的 key 是以 url. 开始的
public class MicroServiceUrl { //专门用于存储配置信息的类
    private String orderUrl; //其中的属性名称和 key 对应的除去 url.部分之外的内容一致,例如这里对应url.orderUrl
    private String userUrl;
    private String shoppingUrl;
// 省去 get 和 set 方法
}

使用@ConfigurationProperties 注解并且使用 prefix 来指定一个前缀,然后该类中的属性名就是配置中去掉前缀后的名字,一一对应即可。即:前缀名+属性名就是配置文件中定义的 key。同时,该类上需要加@Component注解,把该类作为组件放到 Spring 容器中,让 Spring 去管理,使用的时候直接注入即可。

需要注意的是,使用@ConfigurationProperties 注解需要导入它的依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

到此为止将配置写好了,接下来写个 Controller 来测试一下。此时不需要在代码中一个个引入这些微服务的 url了,直接通过@Resource 注解将刚刚写好配置类注入进来即可使用了,非常方便。

java 复制代码
@RestController
@RequestMapping("/test")
public class TestController {
    private static final Logger LOGGER = LoggerFactory.getLogger(TestController.class);
    @Resource 可以使用 Autowired //按照类型自动装配,也可以使用 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

注意:使用@Value 获取配置数据和通过配置参数 bean 的方式获取配置数据,两者不互斥,可以同时使用

java 复制代码
@RestController
@RequestMapping("/test")
public class TestController {
    @Value("${url.orderUrl}")
    private String orderURL;
    @Autowired
    private MicroServiceUrl microServiceUrl;
    private static final Logger logger= LoggerFactory.getLogger(TestController.class);
    @GetMapping("/params")
    public String params(){
        logger.warn("========="+orderURL);
        logger.error("========="+microServiceUrl.getOrderUrl());
        logger.error("========="+microServiceUrl.getUserUrl());
        return "success";
    }
}

3、指定项目配置文件

在实际项目中,一般有两个环境:开发环境和生产环境。开发环境中的配置和生产环境中的配置往往不同,比如环境、端口、数据库、相关地址等。实际上不可能在开发环境调试好之后,部署到生产环境后,又要将配置信息全部修改成生产环境上的配置,这样太麻烦,也不科学。

最好的解决方法就是开发环境和生产环境都有一套对用的配置信息,然后当在开发时,指定读取开发环境的配置,当将项目部署到服务器上之后,再指定去读取生产环境的配置。

新建两个配置文件:application-dev.yml 和 application-prod.yml,分别用来对开发环境和生产环境进行相关配置。这里为了方便分别设置两个访问端口号,开发环境用 8001,生产环境用 8002.

yml 复制代码
# 开发环境配置文件
server:
   port: 8001
# 生产环境配置文件
server:
   port: 8002

然后在 application.yml 文件中指定读取哪个配置文件即可。比如在开发环境下指定读取 applicationn-dev.yml文件

yml 复制代码
spring:
   profiles:
   active: 
   - dev

这样就可以在开发的时候,指定读取 application-dev.yml 文件,访问的时候使用 8001 端口,部署到服务器后,只需要将 application.yml 中指定的文件改成 application-pro.yml 即可,然后使用 8002 端口访问,非常方便。

注意:这里不是相互覆盖定义,而是只有一个配置文件生效,具体哪个配置生效却决于 active 的值。例如 active为 abc,则自动查询对应的 application-abc.yml 文件

4、总结

这里主要了解 Spring Boot 中在业务代码中读取相关配置,包括单一配置和多个配置项,在微服务中,这种情况非常常见,往往会有很多其他微服务需要调用,所以封装一个配置类来接收这些配置是个很好的处理方式。

除此之外,例如数据库相关的连接参数等,也可以放到一个配置类中,其他遇到类似的场景,都可以这么处理。

最后了解开发环境和生产环境配置的快速切换方式,省去了项目部署时,诸多配置信息的修改。

相关推荐
哎呦没11 分钟前
SpringBoot框架下的资产管理自动化
java·spring boot·后端
2401_8576009514 分钟前
SpringBoot框架的企业资产管理自动化
spring boot·后端·自动化
m0_571957582 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功4 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
种树人202408194 小时前
如何在 Spring Boot 中启用定时任务
spring boot
Chrikk6 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*6 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue6 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang