【问题标题】:Spring multiple @ConfigurationProperties with same class具有相同类的多个@ConfigurationProperties
【发布时间】:2019-12-28 02:47:09
【问题描述】:

我有一门这样的课:

@Data
@Component
@ConfigurationProperties("a.config.props")
public class ClientProperties {

    private String hostname;
    private String port;
    private String baseUrl;
    private String endpoint;
}

我有数十个属性上下文,但对于 1 行,我必须重复整个课程。有没有一种简单而优雅的方法来拥有一个类并以某种方式动态传递属性上下文(可能是一个数组或类似的东西),以便我使用同一个类。

【问题讨论】:

    标签: java spring spring-boot properties


    【解决方案1】:

    您可以只使用一个类来描述您众多且相同的属性块;

    @Data
    public class ClientProperties {
        private String hostname;
        private String port;
        private String baseUrl;
        private String endpoint;
    }
    

    然后引用它以将单个类与不同的属性块链接;

    @Configuration
    public class PropertyConfigurer {
    
        @Bean
        @ConfigurationProperties("props.one")
        private ClientProperties propsOne() {
            return new ClientProperties();
        }
    
        @Bean
        @ConfigurationProperties("props.two")
        private ClientProperties propsTwo() {
            return new ClientProperties();
        }
    
        @Bean
        @ConfigurationProperties("props.three")
        private ClientProperties propsThree() {
            return new ClientProperties();
        }
    }
    

    然后你可以通过它们的方法名作为限定符来访问它们;

    @Component
    public class SomeService {
    
        @Autowired
        private ClientProperties propsOne;
        @Autowired
        private ClientProperties propsTwo;
        @Autowired
        private ClientProperties propsThree;
    
        ... some logic
    }
    

    【讨论】:

    • 我还需要许多实例,因此 clientProperties 的范围为 prototype。那么我可以摆脱类PropertyConfigurer 吗?
    • @Raghuveer 为什么要摆脱课程?我不明白你的意思。您必须这样定义才能将每个属性块的类结构与其在属性文件中的路径绑定。您不能只使用 ClientProperties@Component 并引用多个块。
    • 感谢您的快速回复。我希望所有的 bean 都由 spring 管理,这就是为什么我想要 prototype 但我希望每个属性上下文都与类绑定并实例化。有什么春季技巧吗?
    • @Raghuveer prototype 范围不会使 bean 由 Spring 管理,所有 bean 都已由 Spring 管理。 prototype 只会为每个新的自动装配创建一个新的 bean 实例 (read about it here)。我的回答应该够你用了。
    • @bauraequete 我个人不喜欢我的代码中的new。所以寻找一些有弹性的东西。但我想它应该足够好,谢谢
    【解决方案2】:

    我建议创建一个包含所有属性的抽象类,并为您拥有的尽可能多的属性变体扩展抽象类。

    @Data
    public abstract class BaseClientProperties {
        private String hostname;
        private String port;
        private String baseUrl;
        private String endpoint;
    }
    
    @Configuration
    @ConfigurationProperties("a.config.props1")
    public class Client1Properties extends BaseClientProperties{
    
    }
    
    @Configuration
    @ConfigurationProperties("a.config.props2")
    public class Client2Properties extends BaseClientProperties{
    }
    

    如下使用它们:

    @Service
    public class SomeService {
    
        @Autowired
        private Client1Properties client1Properties;
        @Autowired
        private Client2Properties client2Properties;
    
        ... service logic
    }
    

    【讨论】:

      【解决方案3】:

      假设您希望主机名作为属性文件的列表,那么您可以像这样重新排列代码:

      @Component
      @ConfigurationProperties("a.config.props")
      @Data
      public class ClientProperties {
          private List<String>  hostname;
          private String port;
          private String baseUrl;
          private String endpoint;
      }
      

      然后您可以将配置属性放在 application.properties 文件中,如下所示:

      a.config.props.hostname[0]=host1.com
      a.config.props.hostname[1]=host2.com
      a.config.props.hostname[2]=host3.com
      a.config.props.port=8080
      a.config.props.baseUrl=baseurl
      a.config.props.endpoint=/thisendpoint
      

      然后只需 @Autowire 你的 ClientProperties 到你想要的类并调用

      List<String> hostnames = clientProperties.getHostname();
      

      您可以根据需要使用它们的值。如果我正确理解您的问题,我认为这将回答它。如果您需要更多信息,请告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 1970-01-01
        • 2018-03-09
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多