java 是否可以在自定义Sping Boot 启动器中使用默认的application.yml?

cbeh67ev  于 2023-04-10  发布在  Java
关注(0)|答案(3)|浏览(147)

我面临着一个问题,我的自定义Spring Boot 启动器和一个 Spring 启动应用消费者,使用作为一个依赖项。我在这两个应用程序.yml,但似乎我正在寻找它的配置是唯一pressent,如果它是在消费者定义。
我在starter中的配置是这样的:

@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中,则starterbean在创建它们时不具有这些属性。
也许我错过了什么?

wwodge7n

wwodge7n1#

如果我正确理解你的问题,我上周就遇到了这样的问题......我正在检查这个问题,我有一些发现(它们没有得到官方文件的支持):如果你添加依赖项并想使用它的资源,你会遇到这样的情况:两个application.yml文件都有相同的位置-classpath:application.yml,或者它们不能一起加载,或者其中一个被另一个覆盖。在任何情况下,在我的应用程序中,它都不起作用。
如果你只需要从依赖的配置文件中加载配置,直接简单的解决方案-重命名它并以可能的方式加载(从YAML手动加载,属性源的初始化器等)。
但是如果这个配置文件应该在任何地方使用,我们可以在上下文中手动加载属性。在依赖项(在您的情况下是消费者)中创建另一个配置文件,例如consumer-application.yml和@configuration class中的next 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文件中的属性。
但最简单的方法-使用属性configs。在这种情况下,您可以在consumer中设置@PropertySource("classpath:consumer-application.properties")@PropertySource(value = {"classpath:application.properties", "classpath:consumer-application.properties"})在我的情况下,两个变体都可以正常工作。

luaexgnf

luaexgnf2#

你可以尝试在启动器本身初始化成员变量。如果消费者想要覆盖这些值,他们可以用他们的应用程序配置来做。

@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。

vnjpjtjt

vnjpjtjt3#

我们有两个选项来设置自定义启动器中定义的属性,使它们在应用程序(使用启动器)中可用。
1.将所有属性放在任何自定义属性文件(例如custom.properties)中,并将其放在src/main/resources文件夹中。现在使用@PropertySource作为将属性源添加到环境中的方便机制。此@PropertySource("classpath:custom.properties")必须放在您的自动配置中。

**工作原理:-*当您在spring Boot 应用程序中添加自定义启动器时,在启动时,您的自动配置将在spring应用程序上下文中配置,并且由于我们在自动配置中使用@PropertySource("classpath:custom.properties"),因此在custom.properties中定义的属性也将在应用程序上下文中可用。 如果您想要覆盖某些属性,请在应用程序本身的application.properties|yml中定义这些属性。*示例:-

custom.properties
welcome.message=你好Akshay

@AutoConfiguration
    @PropertySource("classpath:custom.properties")
    public class MyAutoConfiguration{
      // spring beans 
    }

1.我们知道,如果两者.属性|自定义启动器中的yml和包含自定义启动器的应用程序命名为application.properties|yml将导致自定义启动器中设置的属性不起作用,因为这两个属性具有相同的名称和相同的路径。虽然我们不能具有相同名称和相同路径的相同属性,但我们可以在同一项目中同时拥有application.ymlapplication.properties阅读此处-Does spring boot support using both properties and yml files at the same time?

**解决方案:-application.properties|yml文件中的所有属性放在src/main/resources文件夹中。这样你就不必使用@PropertySource。但是在使用这个选项时你只需要记住一件事(a)如果你的应用程序的资源文件名为application.yml,那么在starter中,你应该有application.properties--〉在这种情况下,你不能通过应用程序的application.yml覆盖属性,因为首先加载application.yml,然后加载application.properties(b)**如果你的应用程序的资源文件名为application.properties,那么在starter中,你应该有application.yml--〉在这种情况下,你可以通过应用程序的application.properties覆盖属性,因为根据上面的语句,application.properties将在application.yml之后加载。

相关问题