V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sankooc
V2EX  ›  Java

请教一个 springboot 配置相关问题

  •  
  •   sankooc ·
    sankooc · 341 天前 · 3280 次点击
    这是一个创建于 341 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有个配置设计相关的需求 大概是这样

    可以理解为提供给一个工厂方法的配置文件

    spring:
       ...
    vendor:
       proto: // 原型缺省值
          name: test
          age: 20
          income: 100
       instance: //实例列表
          - X
          - Y
       instaceConfig:
          X:
             age: 23 // 具体实例覆盖缺省值字段
          Y:
             name: test4 // 具体实例覆盖缺省值字段
    
    

    java 代码的预期

    
       Vendor v1 = vendorProvider.create("X");
       system.out.print(v1.name) //test
       system.out.print(v1.age) //23
    
       Vendor v2 = vendorProvider.create("Y");
       system.out.print(v2.name) //test4
    

    现在问题是动态的获取 application.yml 中的字段 StringValueResolver 可以满足动态获取但是 但是获取未配置字段时会报出异常 明显并不是优雅的方案 各位有没有人遇上过类似的需求

    6 条回复    2023-12-19 11:23:11 +08:00
    securityCoding
        1
    securityCoding  
       341 天前
    这个是 yaml 库抛出的 runtime 异常吧,你自己包装一个方法就好了?
    xuanbg
        2
    xuanbg  
       341 天前
    使用变量前自己先判空就行了
    imokkkk
        3
    imokkkk  
       341 天前
    把 getXXX 方法重写了?
    fykang
        4
    fykang  
       340 天前
    优雅做法你应该写成 map 的方式注入配置,可以参考 security 中关于不同的 resource 的注入
    根据你的示例可以改写成

    配置文件
    ```yml
    spring:
    ...
    vendor:
    proto: // 原型缺省值
    name: test
    age: 20
    income: 100
    instance: //实例列表
    X:
    age: 23 // 具体实例覆盖缺省值字段
    Y:
    name: test4 // 具体实例覆盖缺省值字段
    ```

    配置类
    ```java

    @Data
    @ConfigurationProperties(prefix = "vendor")
    public class VendorProperties {

    private Instance proto;

    private Map<String,Instance> instanceMap;

    @Data
    public static class Instance{
    private Integer age;
    private String name;
    private Integer income;
    }

    }
    ```
    注入配置
    ```java
    @Configuration
    @EnableConfigurationProperties({VendorProperties .class})
    public class MayConfigurer {

    @Autowired
    private VendorProperties vendorProperties;



    public void doCreate(){
    // todo 拿到这个配置类就可以写的的具体工厂方法了

    Instance proto = vendorProperties.getProto();

    // 灵活的方式改成遍历 entrySet 的方式最好,下面我就简单写一下获取不同的配置方式

    Instance x = vendorProperties.getInstanceMap().get("X");

    Instance y = vendorProperties.getInstanceMap().get("Y");

    }

    }
    ```
    fykang
        5
    fykang  
       340 天前
    排版乱了,重新发一下


    优雅做法你应该写成 map 的方式注入配置,可以参考 security 中关于不同的 resource 的注入
    根据你的示例可以改写成

    配置文件
    ```yml
    vendor:
    proto: # 原型缺省值
    name: test
    age: 20
    income: 100
    instance: //实例列表
    X:
    age: 23 # 具体实例覆盖缺省值字段
    Y:
    name: test4 # 具体实例覆盖缺省值字段
    ```

    配置类
    ```java

    @Data
    @ConfigurationProperties(prefix = "vendor")
    public class VendorProperties {

    private Instance proto;

    private Map<String,Instance> instanceMap;

    @Data
    public static class Instance{
    private Integer age;
    private String name;
    private Integer income;
    }
    }
    ```
    注入配置
    ```java
    @Configuration
    @EnableConfigurationProperties({VendorProperties .class})
    public class MayConfigurer {

    @Autowired
    private VendorProperties vendorProperties;



    public void doCreate(){
    // todo 拿到这个配置类就可以写的的具体工厂方法了

    Instance proto = vendorProperties.getProto();

    // 灵活的方式改成遍历 entrySet 的方式最好,下面我就简单写一下获取不同的配置方式

    Instance x = vendorProperties.getInstanceMap().get("X");

    Instance y = vendorProperties.getInstanceMap().get("Y");

    }

    }
    ```
    fykang
        6
    fykang  
       340 天前
    算了,我放弃排版了,你应该能理解吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2727 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 09:49 · PVG 17:49 · LAX 01:49 · JFK 04:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.