【问题标题】:How to inject prefixed properties into java.util.Properties?如何将前缀属性注入 java.util.Properties?
【发布时间】:2018-01-24 07:42:26
【问题描述】:

Spring boot 提供了一种优雅的方式来使用@ConfigurationProperties(prefix = "foo") 将带有特定键前缀的属性注入到配置类中。这显示为herehere。问题是,如何将前缀属性注入java.util.Properties 实例,如下所示?

@Configuration
@EnableConfigurationProperties
public class FactoryBeanAppConfig {

    @Bean
    @ConfigurationProperties(prefix = "kafka")
    public Producer<String, String> producer(Properties properties) throws Exception {
        Producer<String, String> producer = new KafkaProducer<String, String>(properties);
        return producer;
    }

}

【问题讨论】:

    标签: java spring spring-mvc spring-boot


    【解决方案1】:

    这是行不通的,因为这个属性注入是基于对象上的 getter 和 setter 应该持有 @ConfigurationProperties 像这样定义一个包含您想要的属性的类:

    @ConfigurationProperties(prefix = "kafka.producer")
    public class MyKafkaProducerProperties {
    
      private int foo;
    
      private string bar;
    
      // Getters and Setter for foo and bar
    
    }
    

    然后像这样在你的配置中使用它

    @Configuration
    @EnableConfigurationProperties(MyKafkaProducerProperties.class)
    public class FactoryBeanAppConfig {
    
      @Bean
      public Producer<String, String> producer(MyKafkaProducerProperties kafkaProperties) throws Exception {
        Properties properties = new Properties();
        properties.setProperty("Foo", kafkaProperties.getFoo());
        properties.setProperty("Bar", kafkaProperties.getBar());
        Producer<String, String> producer = new KafkaProducer<String, String>(properties);
        return producer;
      }
    }
    

    更新

    由于您评论说您不想将每个属性都表示为 java 代码,您可以使用 HashMap 作为 @ConfigurationProperties 中唯一的属性

    @ConfigurationProperties(prefix = "kafka")
    public class MyKafkaProducerProperties {
    
      private Map<String, String> producer= new HashMap<String, String>();
    
      public Map<String, String> getProducer() {
        return this.producer;
      }
    }
    

    在您的application.properties 中,您可以像这样指定属性:

    kafka.producer.foo=hello
    kafka.producer.bar=world
    

    在您的配置中,您可以像这样使用它:

    @Configuration
    @EnableConfigurationProperties(MyKafkaProducerProperties.class)
    public class FactoryBeanAppConfig {
    
      @Bean
      public Producer<String, String> producer(MyKafkaProducerProperties kafkaProperties) throws Exception {
    
        Properties properties = new Properties();
    
        for ( String key : kafkaProperties.getProducer().keySet() ) {
         properties.setProperty(key, kafkaProperties.getProducer().get(key));
        }
    
        Producer<String, String> producer = new KafkaProducer<String, String>(properties);
        return producer;
      }
    }
    

    【讨论】:

    • 谢谢,Yannnic。我明白为什么我的代码不起作用。你能解释一种自动注入前缀属性的方法吗?这样我就可以将属性外部化,而无需硬编码属性名称(setProperty())。
    • @Value 注释可以满足我的想法。通过这种方式,您可以将属性注入您的 bean。看看这个指南:baeldung.com/spring-value-annotation
    • 是的,它确实将属性直接注入到字段中。 KafkaProducer 类来自第三方 API,我想将属性按原样(由 application.properties 提供)传递给它,但以“kafka”为前缀,这样就可以添加任何新属性而无需向MyKafkaProducerProperties 添加新字段。因此,我试图找到如何将前缀属性注入 java.util.Properties 的答案? PropertySource?
    • 嗯,也许您可​​以在配置属性中使用 HashMap 作为字段。我会更新我的答案。给我一秒钟
    【解决方案2】:

    你可以定义一个带有@ConfigurationProperties注解的新bean,像这样:

    @Bean
    @ConfigurationProperties(prefix = "kafka")
    public Properties kafkaProperties() {
        return new Properties();
    }
    
    @Bean
    public Producer<String, String> producer() throws Exception {
        return new KafkaProducer<String, String>(kafkaProperties());
    }
    

    (取自https://stackoverflow.com/a/50810923/500478

    【讨论】:

      猜你喜欢
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 2010-10-26
      • 2011-01-16
      • 1970-01-01
      • 2016-10-16
      • 2015-04-25
      • 2017-09-07
      相关资源
      最近更新 更多