quarkus实战之七:使用配置

这篇具有很好参考价值的文章主要介绍了quarkus实战之七:使用配置。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

本篇概览

  • 本文是《quarkus实战》系列的第七篇,前文讲述了如何在将配置信息传入quarkus应用,今天要练习的是如何使用这些配置信息
  • 整篇文章由以下内容构成:
  1. 创建工程,作为演示使用配置项操作的代码
  2. 演示最基本的使用配置项操作
  3. 展示配置项不存时会导致什么问题
  4. 演示如何设置默认值,这样配置项不存在也不会出错
  5. 默认值是字符串,而实际的变量可以是多种类型,它们之间的关系
  6. Optional类型的配置注入
  7. 不用注解注入,也可以写代码获取配置
  8. 针对相同前缀的配置项,使用配置接口简化代码
  9. 使用配置接口嵌套,简化多级的相同前缀配置项
  10. 用map接受配置信息(减少配置项相关代码量)
  11. quarkus及其扩展组件的内置配置项
  • 接下来从创建demo工程开始吧

演示代码

  • 创建一个demo工程,参考下面的命令,这样的工程会自带一个web服务类HobbyResource.java
mvn "io.quarkus:quarkus-maven-plugin:create" \
  -DprojectGroupId="com.bolingcavalry" \
  -DprojectArtifactId="hello-quarkus" \
  -DprojectVersion="1.0-SNAPSHOT" \
  -DclassName="HobbyResource" \
  -Dpath="actions"

最基本的配置

  • 先来看看最常用最基本的配置文件使用方式
  • 打开文件src/main/resources/application.properties,增加下面这行配置
greeting.message = hello from application.properties
  • 打开HobbyResource.java,增加如下成员变量,使用了注解ConfigProperty
  @ConfigProperty(name = "greeting.message") 
  String message;
  • 以上就是最简单的使用配置项的方式,程序运行后,application.properties中greeting.message的值就会被quarkus框架注入到message成员变量中

配置项不存在导致的异常

  • 如果ConfigProperty注解的配置项在配置文件中不存在,应用启动会报错,来看看是什么错误
  • 将HobbyResource.java的代码改成下面这样,成员变量notExistsConfig的配置项是not.exists.config,这个配置项在配置文件中并不存在
@Path("/actions")
public class HobbyResource {

    // 配置文件中不存在名为not.exists.config的配置项
    @ConfigProperty(name = "not.exists.config")
    String notExistsConfig;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello RESTEasy, " + LocalDateTime.now() + ", [" + notExistsConfig + "]";
    }
}
  • 启动应用时报错如下图所示,红框中提示加载配置项失败
    quarkus实战之七:使用配置

带默认值的配置

  • 对于上面演示的配置项不存在导致启动失败问题,可以给ConfigProperty注解设置默认值,这样一旦找不到配置项,就使用默认值注入,可以避免启动失败了
  • HobbyResource.java的源码如下,成员变量notExistsConfig的注解了增加属性defaultValue
@Path("/actions")
public class HobbyResource {

    // 配置文件中不存在名为not.exists.config的配置项
    @ConfigProperty(name = "not.exists.config", defaultValue = "112233")
    String notExistsConfig;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello RESTEasy, " + LocalDateTime.now() + ", [" + notExistsConfig + "]";
    }
}
  • 再次启动应用,这次不报错了,浏览器访问结果如下图,defaultValue已经生效
    quarkus实战之七:使用配置

defaultValue属性的自动转换

  • 对于ConfigProperty注解的defaultValue属性还有一点要注意,来看ConfigProperty的源码,如下图,红框显示defaultValue的类型是String
    quarkus实战之七:使用配置
  • 上图中,defaultValue的注释有说明:如果ConfigProperty注解修饰的变量并非String型,那么defaultValue的字符串就会被自动quarkus字符转换
  • 例如修饰的变量是int型,那么defaultValue的String类型的值会被转为int型再赋给变量,如下所示,notExistsConfig是int型,defaultValue的字符串可以被转为int:
// 配置文件中不存在名为not.exists.config的配置项
@ConfigProperty(name = "not.exists.config", defaultValue = "123")
int notExistsConfig;
  • 如果把上面代码中的defaultValue的值从123改为xxx,此时应用启动就会失败,因为“xxx”转为int的过程中抛出了异常,如下图:
    quarkus实战之七:使用配置
  • 除了上面试过的int,还有很多种类型都支持从defaultValue的字符串值被自动转换,它们是:
  1. 基础类型:如boolean, byte, short
  2. 装箱类型:如java.lang.Boolean, java.lang.Byte, java.lang.Short
  3. Optional类型:java.util.Optional, java.util.OptionalInt, java.util.OptionalLong, and java.util.OptionalDouble
  4. java枚举
  5. java.time.Duration
  6. JDK网络对象:如java.net.SocketAddress, java.net.InetAddress
  • 例如,下面是字符串自动转InetAddress的例子,可以正常运行:
@ConfigProperty(name = "server.address", defaultValue = "192.168.1.1")
InetAddress serverAddress;
  • 如果ConfigProperty修饰的变量是boolean型,或者Boolean型,则defaultValue值的自动转换逻辑有些特别: "true", "1", "YES", "Y" "ON"这些都会被转为true(而且不区分大小写,"on"也被转为true),其他值会被转为false
  • 还有一处要注意的:defaultValue的值如果是空字符串,就相当于没有设置defaultValue,此时如果在配置文件中没有该配置项,启动应用会报错

支持Optional

  • 支持Optional这个特性很赞,首先Optional类型的成员变量可直接用于函数式编程,其次配置项不存在时又能避免启动失败
  • 接下来试试用ConfigProperty注解修饰Optional类型的成员变量
  • HobbyResource.java的源码如下,optionalMessage是Optional类型的成员变量,配置项optional.message就算不存在,应用也能正常启动,并且optionalMessage直接用于函数式编程中(optionalMessage.ifPresent)
@Path("/actions")
public class HobbyResource {

    // 配置文件中存在名为greeting.message的配置项
    @ConfigProperty(name = "greeting.message")
    String message;

    // 配置文件中,不论是否存在名为optional.message的配置项,应用都不会抛出异常
    @ConfigProperty(name = "optional.message")
    Optional<String> optionalMessage;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        List<String> list = new ArrayList<>();
        list.add(message);

        // 只有配置项optional.message存在的时候,才会执行list.add方法
        optionalMessage.ifPresent(list::add);

        return "Hello RESTEasy, " + LocalDateTime.now() + ", " + list;
    }
}
  • 先看配置项optional.message存在的情况,如下图红框所示,optional.message在配置文件中是个正常的配置项
    quarkus实战之七:使用配置
  • 启动应用,浏览器访问web接口,如下图,optional info是配置项optional.message的值
    quarkus实战之七:使用配置
  • 现在将optional info从文件application.properties中删除,重启应用,再次访问浏览器,如下图,应用依然正常响应,list中只有成员变量message的内容:
    quarkus实战之七:使用配置

编码获取配置项

  • 除了用ConfigProperty注解来获取配置项的值,还可以用写代码的方式获取
  • 下面的代码展示了通过API获取配置项的操作,请注意代码中的注释
@Path("/actions")
public class HobbyResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        List<String> list = new ArrayList<>();

        // 可以用静态方法取得Config实例
        Config config = ConfigProvider.getConfig();

        // getValue可取得指定配置项的指定类型值
        String greet = config.getValue("greeting.message", String.class);

        list.add(greet);

        // getOptionalValue可以将配置项的值包状为Optional对象,如果配置项不存在,也不会报错
        Optional<String> optional = config.getOptionalValue("not.exists.config", String.class);

        // 函数式编程:只用optional中有对象时,才会执行list.add方法
        optional.ifPresent(list::add);

        return "Hello RESTEasy, " + LocalDateTime.now() + ", " + list;
    }
}
  • 当配置项not.exists.config不存在时,页面响应如下,只有greeting.message配置项的值:
    quarkus实战之七:使用配置
  • 配置项not.exists.config=123456时,页面响应如下,两个配置项的值都能成功获取:
    quarkus实战之七:使用配置
  • 另外,官方建议不要使用System.getProperty(String) System.getEnv(String)去获取配置项了,它们并非quarkus的API,因此quarkus配置相关的功能与它们并无关系(例如感知配置变化、自动转换类型等)

配置接口

  • 假设配置项如下,都是相同的前缀student
student.name=Tom
student.age=11
student.description=He is a good boy
  • 针对上述配置项,可以用注解ConfigMapping将这些它们集中在一个接口类中获取,接口类StudentConfiguration.java如下
package com.bolingcavalry;

import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
import io.smallrye.config.WithName;

@ConfigMapping(prefix = "student")
public interface StudentConfiguration {
    /**
     * 名字与配置项一致
     * @return
     */
    String name();

    /**
     * 名字与配置项一致,自动转为int型
     * @return
     */
    int age();

    /**
     * 名字与配置项不一致时,用WithName注解指定配置项
     * @return
     */
    @WithName("description")
    String desc();

    /**
     * 用WithDefault注解设置默认值,如果配置项"student.favorite"不存在,则默认值生效
     * @return
     */
    @WithDefault("default from code")
    String favorite();
}
  • 从上述代码可见,一个接口即可完成所有配置项的注入,在使用这些配置项的时候,只要注入StudentConfiguration实例即可
  • 首先要用ConfigMapping指明配置项的前缀,该接口中的方法都对应具有此前缀的配置项
  • 一般情况下,方法名就等于配置项的名称,也可以用WithName指定配置项名称
  • WithDefault指定默认值,如果找不到配置项就用此默认值
  • 来看看如何使用这个配置接口,web服务代码如下,只要依赖注入StudentConfiguration即可,不在需要为每个配置项都用成员变量和ConfigProperty注解了
package com.bolingcavalry;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.time.LocalDateTime;

@Path("/actions")
public class HobbyResource {

    @Inject
    StudentConfiguration student;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {

        return "Hello RESTEasy, "
                + LocalDateTime.now()
                + " [" + student.name() + "], "
                + " [" + student.age() + "], "
                + " [" + student.desc() + "], "
                + " [" + student.favorite() + "]";
    }
}
  • 运行代码,用浏览器访问web接口试试,如下图,所有配置项都能正确获取

quarkus实战之七:使用配置

配置项是多个单词时,如何对应配置接口的方法?

  • 回顾刚才的配置,name、age、description这些都是单个单词,现在如果有个配置项是多个单词,例如学号的英文是student number,应该如何转为StudentConfiguration接口的方法呢?
  • 首先要看您的匹配项的命名风格,对多个单词是如何分隔的,一般有这三种:
  1. 减号分隔:student-number
  2. 下划线分隔:student_number
  3. 驼峰命名:studentNumber
  • ConfigMapping注解提供了namingStrategy的属性,其值有三种,分别对应上述三种命名风格,您根据自身情况选用即可
  1. KEBAB_CASE(默认值):减号分隔的配置项转为驼峰命令的方法,配置项student-number对应的方法是studentNumber
  2. SNAKE_CASE:下划线分隔的配置项转为驼峰命令的方法,配置项student_number对应的方法是studentNumber
  3. VERBATIM:完全对应,不做任何转换,配置项student_number对应的方法是student_number
  • 使用namingStrategy属性的示例代码如下
@ConfigMapping(prefix = "student", namingStrategy = ConfigMapping.NamingStrategy.SNAKE_CASE)
public interface StudentConfiguration {
    /**
     * 名字与配置项一致
     * @return
     */
    String name();
    ...

配置接口嵌套

  • 再来看下面的配置,有两个配置项的前缀都是student.address,给人的感觉像是student对象里面有个成员变量是address类型的,而address有两个字段:province和city
student.name=Tom
student.age=11
student.description=He is a good boy

student.address.province=guangdong
student.address.city=shenzhen
  • 针对上述配置,quarkus支持用接口嵌套来导入,具体做法分为两步,首先新增一个接口Address.java,源码如下
package com.bolingcavalry;

public interface Address {
    String province();
    String city();
}
  • 第二步,在配置接口StudentConfiguration.java中,增加下图红框中的一行代码(接口中返回接口,形成接口嵌套)

quarkus实战之七:使用配置

  • 最后,修改HobbyResource.java代码,增加下图红框中的两行,验证能否正常取得address前缀的配置项目

quarkus实战之七:使用配置

  • 重启应用,如下图,配置项可以正常获取

quarkus实战之七:使用配置

配置项转为map

  • 前面的接口嵌套,虽然将多层级的配置以对象的形式清晰的表达出来,但也引出一个问题:配置越多,接口定义或者接口方法就越多,代码随之增加
  • 如果配置项的层级简单,还有种简单的方式将其映射到配置接口中:转为map
  • 依然以下面的配置项为例
student.address.province=guangdong
student.address.city=shenzhen
  • 对应的代码改动如下图,只要把address方法的返回值从Address改为Map<String, String>即可,这样修改后,address层级下面再增加配置项,也不用修改配置项有关的代码了:

quarkus实战之七:使用配置

  • 使用配置的业务代码也要改,如下图,改为从map中获取

quarkus实战之七:使用配置

  • 部署运行验证,可以正常取值

quarkus实战之七:使用配置

内置配置项

  • quarkus有很多内置的配置项,例如web服务的端口quarkus.http.port就是其中一个,如果您熟悉SpringBoot的话,对这些内置配置项应该很好理解,数据库、消息、缓存,都有对应配置项

  • 篇幅所限就不在此讲解quarkus内置的配置项了,您可以参考这份官方提供的配置项列表,里面有详细说明:https://quarkus.io/guides/all-config

  • 上述文档中,有很多配置项带有加锁的图标,如下图红框所示,有这个图标的配置项,其值在应用构建的时候已经固定了,在应用运行期间始终保持只读状态
    quarkus实战之七:使用配置

  • 这种带有加锁图标的配置项的值,在应用运行期间真的不能改变了吗?其实还是有办法的,官方文档指明,如果业务的情况特殊,一定要变,就走热部署的途径,您可以参考《quarkus实战之四:远程热部署》

  • 官方对开发者的建议:在开发quarkus应用的时候,不要使用quarkus作为配置项的前缀,因为目前quarkus框架及其插件们的配置项的前缀都是quarkus,应用开发应该避免和框架使用相同的配置项前缀,以免冲突

  • 至此,咱们已经学习了如何在quarkus应用中使用配置项,接下来还会一起实践更多的quarkus基础知识,锁定《quarkus实战》专辑,欣宸不会辜负您的期待

欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...文章来源地址https://www.toymoban.com/news/detail-606532.html

到了这里,关于quarkus实战之七:使用配置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ruoyi项目服务器重启后台报:欢迎使用RuoYi后台管理框架,当前版本:v3.8.1,请通过前端地址访问。

    阿西,真的想骂人,不会耶,根本不会,咱就不明白了,怎么好好的项目在服务器上运行的好好的,不就是服务器到期了停了一下子再续上重启,再进去跟后台系统,就欢迎使用RuoYi后台管理框架,当前版本:v3.8.1,请通过前端地址访问。,真的好烦,不是自己写的代码,也

    2024年02月04日
    浏览(38)
  • 【git】配置代理访问github

    参考大神的方法 没有解决。 GitHub访问加速 简直完美! C:Userszhangbin.ssh 报错 通过clash 一定要allow lan 一定有system proxy zhangbin@DESKTOP-1723CM1 MINGW64 /g/CDN/NET-EQ-DEV zhangbin@DESKTOP-1723CM1 MINGW64 /g/CDN/NET-EQ-DEV $ git clone https://github.com/TaoistKing/AudioPlc.git Cloning into ‘AudioPlc’… remote: Enumerati

    2024年01月25日
    浏览(38)
  • 访问GitHub的host配置

    注意:随着时间推移,以上ip可能失效,如果失效,可在这里查询:“github.com”A记录/cname检测结果--Dns查询|dns查询--站长工具

    2024年02月13日
    浏览(52)
  • quarkus实战之一:准备工作

    这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 《quarkus实战》系列是欣宸在2022年春季推出的又一个精品原创系列,作者将自己对java的热爱渗透到每段文字和每行代码中,全系列秉承欣宸一贯的知识+实战风格,既有知识普及、更有实际操作,在涉

    2024年02月16日
    浏览(41)
  • quarkus实战之八:profile

    这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本文是《quarkus实战》系列的第八篇,经过前面的学习,咱们对配置有了足够了解,但问题也随之而来:如何让应用以最小的改动同时运行在不同环境(如本地、测试、生产等) 举个例子,下面是个

    2024年02月15日
    浏览(32)
  • UDS诊断系列之七 安全访问(27)服务(番外)附录I

    附录I的主要内容是通过一个状态图来描述ECU在安全访问的各状态之间的切换条件,以及如何进行状态切换即切换过程中都需要执行哪些操作。 下面直接先上图。 图看起来流程很多,但实际上很简单,先说图中的四个状态: A - ECU没有接收过任何安全访问的请求,或者刚刚接

    2024年02月10日
    浏览(49)
  • [github配置] 远程访问仓库以及问题解决

    作者:20岁爱吃必胜客(坤制作人),近十年开发经验, 跨域学习者,目前于 新西兰奥克兰大学攻读IT硕士学位 。 荣誉: 阿里云博客专家认证 、腾讯开发者社区优质创作者,在CTF省赛校赛多次取得好成绩。 跨领域学习 ,喜欢摄影、弹吉他、咏春拳。 文章深入浅出、语言风

    2024年02月05日
    浏览(55)
  • quarkus实战之四:远程热部署

    将本地的改动极速同步到远程服务端,并自动生效,掌握此技能,开发调试会更高效 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本文是《quarkus实战》系列的第四篇,如标题所示,今天的任务是完成远程热部署实战 作为一名Java程序员,以下场

    2024年02月16日
    浏览(37)
  • quarkus实战之五:细说maven插件

    quarkus的maven插件非常重要,管理和构建工程时都离不开,本篇就来一起了解和掌握它 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本文是《quarkus实战》系列的第五篇,一起去熟悉quarkus的maven插件(就是下图红框中的那个plugin),用好它可以使

    2024年02月16日
    浏览(35)
  • quarkus实战之二:应用的创建、构建、部署

    这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本文是《quarkus实战》系列的第二篇,目标是开发HelloWorld应用,让我们对quarkus有最基本的了解,写好的代码会在以下几种场景运行,这应该覆盖了大部分运行情况,绿色背景的表示具体的运行方式,

    2024年02月16日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包