繁体   English   中英

是否可以在自定义 Spring boot starter 中使用默认 application.yml?

[英]Is it possible to have a default application.yml in a custom Spring boot starter?

我的自定义 Spring Boot 启动器和用作依赖项的 Spring Boot 应用程序使用者存在问题。 我在两个 application.yml 中都有,但似乎我正在寻找的配置只有在消费者中定义时才有意义。

我在启动器中的配置是这样的:

@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "security")
public class StarterSecurityConfig {
    private boolean jwtEnabled;
    private String[] unsecuredPaths;
    private String[] securedPaths;
}

我在 AutoConfiguration 类中定义了这个 bean:

@Bean
public StarterSecurityConfig starterSecurityConfig() {
    return new StarterSecurityConfig();
}

它由具有此 application.yml 和另一个变量的使用者完美检索:

    security:
  jwt-enabled: true
  secured-paths:
    - /user/**
  unsecured-paths:
    - /**

但是,如果我从使用者中删除它并将其放在 starter 的 application.yml 中,则 starter beans 在创建它们时没有这些属性。

也许我错过了什么?

如果我正确理解你的问题,我上周就遇到过这样的问题......我正在检查这个问题并且我有一些发现(官方文档不支持它们):如果你添加依赖并想要使用它的资源,你有一种情况,即两个 application.yml 文件具有相同的位置 - classpath:application.yml ,或者它们不能一起加载,或者其中一个被另一个覆盖。 无论如何,在我的应用程序中,它不起作用。

如果您只需要从依赖的配置文件加载配置,那么直接而简单的解决方案 - 重命名它并以可能的方式加载(从 YAML 手动加载、属性源的初始值设定项等)

但是如果这个配置文件应该在任何地方使用,我们可以在上下文中手动加载属性。 在依赖项(在您的情况下为消费者)中创建另一个配置文件,例如 consumer-application.yml 和 @configuration 类中的下一个 bean:

@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
    var propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
    var yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
    yamlPropertiesFactoryBean.setResources(new ClassPathResource("consumer-application.yaml"));
    propertySourcesPlaceholderConfigurer.setProperties(yamlPropertiesFactoryBean.getObject());
    return propertySourcesPlaceholderConfigurer;
}

并且您可以在带有@Value 的两个应用程序中使用来自 YAML 文件的属性。

但最简单的方法 - 使用属性配置。 在这种情况下,您可以在消费者和@PropertySource(value = {"classpath:application.properties", "classpath:consumer-application.properties"})设置@PropertySource("classpath:consumer-application.properties") @PropertySource(value = {"classpath:application.properties", "classpath:consumer-application.properties"})在我的情况两种变体都能正常工作。

您可以尝试在 starter 本身上初始化成员变量。 如果消费者想要覆盖这些值,他们可以使用应用程序配置来实现。

@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "security")
public class StarterSecurityConfig {
    private boolean jwtEnabled = true;
    private String[] unsecuredPaths = { "/user/**" };
    private String[] securedPaths = { "/**" };
}

更多的想法:

我会将 jwtEnabled 设为 false,并从上面的类中删除 @Configuration 和 @ConfigurationProperties 并使用其他 bean 创建一个 SecurityAutoConfiguration 类。

@Configuration
public class SecurityAutoConfiguration{

   @Bean
   @ConfigurationProperties(prefix = "security")
   public StarterSecurityConfig starterSecurityConfig(){
     return new StarterSecurityConfig();
   }

   @Bean
   @ConditionalOnProperty(value="security.jwtEnabled", havingValue = "true")
   public JwtService jwtService(StarterSecurityConfig starterSecurityConfig) {
     return new JwtService(starterSecurityConfig);
   }   

}

消费者将能够使用 security.jwtEnabled 标志通过他们的应用程序配置启用或禁用 security-starter。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM