【问题标题】:How to pass a Map<String, String> with application.properties如何使用 application.properties 传递 Map<String, String>
【发布时间】:2014-10-09 10:10:04
【问题描述】:

我在需要配置的 web 服务中实现了一些授权。

目前,用户/密码组合被硬编码到 bean 配置中。我想将带有用户和密码的地图配置到 application.properties 中,以便配置可以是外部的。

关于如何做到这一点的任何线索?

<bean id="BasicAuthorizationInterceptor" class="com.test.BasicAuthAuthorizationInterceptor">
    <property name="users">
        <map>
            <entry key="test1" value="test1"/>
            <entry key="test2" value="test2"/>
        </map>
    </property>
</bean>

【问题讨论】:

    标签: spring spring-boot


    【解决方案1】:

    您可以使用@ConfigurationProperties 将来自application.properties 的值绑定到一个bean。为此,您需要注释创建 bean 的 @Bean 方法:

    @Bean
    @ConfigurationProperties
    public BasicAuthAuthorizationInterceptor interceptor() {
        return new BasicAuthAuthorizationInterceptor();
    }
    

    作为 bean 初始化的一部分,BasicAuthAuthorizationInterceptor 上的任何属性都将根据应用程序的环境进行设置。例如,如果这是你的 bean 的类:

    public class BasicAuthAuthorizationInterceptor {
    
        private Map<String, String> users = new HashMap<String, String>();
    
        public Map<String, String> getUsers() {
            return this.users;
        }
    }
    

    这是你的 application.properties:

    users.alice=alpha
    users.bob=bravo
    

    然后users 映射将填充两个条目:alice:alphabob:bravo

    这是一个将所有内容组合在一起的小型示例应用:

    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @EnableAutoConfiguration
    @EnableConfigurationProperties
    public class Application {
    
        public static void main(String[] args) throws Exception {
            System.out.println(SpringApplication.run(Application.class, args)
                    .getBean(BasicAuthAuthorizationInterceptor.class).getUsers());
        }
    
        @Bean
        @ConfigurationProperties
        public BasicAuthAuthorizationInterceptor interceptor() {
            return new BasicAuthAuthorizationInterceptor();
        }
    
        public static class BasicAuthAuthorizationInterceptor {
    
            private Map<String, String> users = new HashMap<String, String>();
    
            public Map<String, String> getUsers() {
                return this.users;
            }
        }
    }
    

    查看javadoc for ConfigurationProperties,了解有关其各种配置选项的更多信息。例如,您可以设置一个前缀,将您的配置划分为多个不同的命名空间:

    @ConfigurationProperties(prefix="foo")
    

    为了使绑定起作用,您必须在 application.properties 中声明的属性上使用相同的前缀:

    foo.users.alice=alpha
    foo.users.bob=bravo
    

    【讨论】:

    • 请注意,您的 bean 应该有一个 getter,以便能够填充地图,而公共字段是不够的。
    • @MeysaM 您是否误读了代码? BasicAuthAuthorizationInterceptor 已经有一个getUsers() 方法并且users 字段是private,而不是public
    • 不,这只是提醒其他所有人不要重复我的错误。您的代码运行良好。
    • 这比接受的答案要好。正是我想要的!
    • metrics.tagsAsSuffix.jvm.gc=metrics.tagsAsSuffix.jvm.threads= 不会被读入 Map&lt;String, List&lt;String&gt;&gt;,每个为空,但 metrics.tagsAsSuffix.jvm = 空列表。后缀的其余部分被删除
    【解决方案2】:

    你可以使用@Value

    属性文件:

    users={test1:'test1',test2:'test2'}
    

    Java 代码:

    @Value("#{${users}}")
    private Map<String,String> users;
    

    【讨论】:

    • 这很好!我们如何从 application.yml 文件中读取地图?如果我们使用 application.yml 文件而不是 application.properties 文件来读取属性,@Value("#{${users}}") 将不起作用
    • 假设我有 50 个这样的属性,所以我不能继续添加 50 次 @Value("#{${users}}"),如果我们可以阅读所有内容,有什么办法吗?还是一口气?
    • 假设我有将近 50 个端点,我不能继续添加@Value("#{${users}}"),我需要一口气阅读所有内容。
    • 不知道为什么这个答案被接受。这在春季靴子世界中尤其具有魅力
    • 如果我的值是string[]或者自定义类,怎么读?例如:private Map&lt;String, String[]&gt; users;private Map&lt;String, User&gt; users;
    【解决方案3】:

    一个java.util.Properties 对象已经是一个Map,实际上是一个HashTable,它又实现了Map

    因此,当您创建一个属性文件(让我们将其命名为 users.properties)时,您应该能够使用 PropertiesFactoryBean&lt;util:properties /&gt; 加载它并将其注入到您的类中。

    test1=test1
    test2=test2
    

    然后做类似的事情

    <util:properties location="classpath:users.properties" id="users" />
    
    <bean id="BasicAuthorizationInterceptor" class="com.test.BasicAuthAuthorizationInterceptor">
        <property name="users" ref="users" />
    </bean>
    

    虽然如果您有 Map&lt;String, String&gt; 作为用户属性的一种类型,它可能会失败...我不会将它们放在 application.properties 文件中。但这可能只是我..

    【讨论】:

      【解决方案4】:

      我认为您正在寻找类似的东西

      http://www.codejava.net/frameworks/spring/reading-properties-files-in-spring-with-propertyplaceholderconfigurer-bean

      您可以类似地从 .properties 中选择值并将其分配给您的地图。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-19
        相关资源
        最近更新 更多