使用配置属性以通用方式填充地图

2022-08-31 14:21:00

我想知道,如果有一种通用方法可以用属性填充地图,你只需要知道前缀。

假设有一堆属性,如

namespace.prop1=value1
namespace.prop2=value2
namespace.iDontKnowThisNameAtCompileTime=anothervalue

我希望有一种通用的方式来填充地图中的此属性,例如

@Component
@ConfigurationProperties("namespace")
public class MyGenericProps {
    private Map<String, String> propmap = new HashMap<String, String>();

    // setter and getter for propmap omitted

    public Set<String> returnAllKeys() {
        return propmap.keySet();
    }
}

或者有没有另一种方便的方法来收集具有特定前缀的所有属性,而不是迭代环境中的所有属性源?

谢谢汉斯乔格


答案 1

只要您乐于将每个属性都添加到地图中,而不仅仅是那些您事先不知道的属性,就可以使用 .如果你想抓取下面的所有内容,那么你需要使用一个空前缀,并为一个名为:@ConfigurationPropertiesnamespacenamespace

@ConfigurationProperties("")
public class CustomProperties {

    private final Map<String, String> namespace = new HashMap<>();

    public Map<String, String> getNamespace() {
        return namespace;
    }

}

Spring Boot 使用该方法检索映射,以便它可以向其添加属性。具有以下属性:getNamespace

namespace.a=alpha
namespace.b=bravo
namespace.c=charlie

地图将包含三个条目:namespace

{a=alpha, b=bravo, c=charlie}

如果属性嵌套得更深,例如:

namespace.foo.bar.a=alpha
namespace.foo.bar.b=bravo
namespace.foo.bar.c=charlie

然后,您将分别用作前缀和重命名和 on。namespace.foonamespacegetNamespaceCustomPropertiesbargetBar

请注意,应应用于您的配置以启用对 的支持。然后,您可以使用该注释引用要处理的任何 Bean,而不是为它们提供方法,或者使用它们来让组件扫描发现它们:@EnableConfigurationProperties@ConfigurationProperties@Bean@Component

@SpringBootApplication
@EnableConfigurationProperties(CustomProperties.class)
public class YourApplication {
    // …
}

答案 2

除此之外,我的问题是我没有多个简单的键/值属性,而是整个对象:

zuul:
  routes:
    query1:
      path: /api/apps/test1/query/**
      stripPrefix: false
      url: "https://test.url.com/query1"
    query2:
       path: /api/apps/test2/query/**
       stripPrefix: false
       url: "https://test.url.com/query2"
    index1:
       path: /api/apps/*/index/**
       stripPrefix: false
       url: "https://test.url.com/index"

按照Jake的建议,我尝试使用带有Pojo的Map,如下所示:

@ConfigurationProperties("zuul")
public class RouteConfig {
    private Map<String, Route> routes = new HashMap<>();

    public Map<String, Route> getRoutes() {
        return routes;
    }

    public static class Route {
        private String path;
        private boolean stripPrefix;
        String url;

        // [getters + setters]
    }
}

像一个魅力一样工作,谢谢!


推荐