是否可以在自定义的 Spring 启动启动器中有一个默认的 application.yml?



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

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

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

我在自动配置类中定义了这个 bean:

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

它被具有此应用程序.yml和另一个变量的消费者完美检索:

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

但是,如果我从消费者中删除它并将其放在启动器的 application.yml 中,则启动器豆在创建它们时没有这些属性。

也许我错过了什么?

如果我正确理解您的问题,我上周才遇到过这样的问题...... 我正在检查这个问题,我有一些发现(官方文档不支持它们(:如果您添加依赖项并想要使用其资源,则会遇到两个 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;
}

而且,您可以在两个应用程序中使用 YAML 文件中的属性@Value。

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

您可以尝试在启动器本身上初始化成员变量。如果使用者想要覆盖这些值,他们可以使用应用程序配置来做到这一点。

@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 标志在其应用程序配置中启用或禁用安全启动器。

我们有 2 个选项来设置自定义启动器中定义的属性,以使它们在应用程序(使用启动器(中可用。

  1. 将所有属性放在任何自定义属性文件(例如 - custom.properties(中,并将其放在src/main/resources文件夹中。现在,使用@PropertySource作为将属性源添加到环境的便捷机制。 此@PropertySource("classpath:custom.properties")必须放在您的自动配置上。
    工作原理:-当您在 Spring 启动应用程序中添加自定义启动器时,在启动时,您的自动配置将在 spring 应用程序上下文中进行配置,并且由于我们在自动配置中使用@PropertySource("classpath:custom.properties"),因此在custom.properties中定义的属性也将在应用程序上下文中可用。如果要重写某些属性,请在应用程序本身的application.properties|yml中定义这些属性。示例:-
    自定义属性

welcome.message=Hello Akshay

@AutoConfiguration
@PropertySource("classpath:custom.properties")
public class MyAutoConfiguration{
// spring beans 
}
         
  1. 我们知道,如果自定义启动器和包含自定义启动器的应用程序中的 .properties|yml 都命名为application.properties|yml将导致自定义启动器中设置的属性不起作用,因为这两个属性具有相同的名称和相同的路径。虽然我们不能具有具有相同名称和相同路径的相同属性,但是我们可以在同一项目中同时拥有application.ymlapplication.properties在这里阅读-Spring 引导是否支持同时使用属性和 yml 文件?
    解决方案:-将所有属性放在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之后加载。

最新更新