使用Spring和YAML注入具有嵌套属性的值

huangapple go评论82阅读模式
英文:

Inject values with Spring and YAML with nested properties

问题

@Value("${autoAgents.supplier}") is not working because you are using HTML entities for double quotes (") instead of actual double quotes ("). Here's the corrected code:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties
@Data
public class TwoConnectConfigurationProperties {
    
    private String activeProfile;
    @Value("${autoAgents.supplier}")
    private AutoAgentDup supplier;
    @Value("${autoAgents.client}")
    private AutoAgentDup client;
}

Make sure to replace " with " as shown above, and it should work as expected.

英文:

I want to inject some values from a YAML to the Spring context.
The structure of the YAML is similar so I did not want to duplicate code, but the Spring startup is failing because it is not being able to inject the value to the placeholder.

Please note my application.properties:

server.port=8084

activeProfile=dev

autoAgents.supplier.id=0
autoAgents.supplier.name=test
autoAgents.supplier.serviceType=REST
autoAgents.supplier.authType=1
autoAgents.supplier.adapter=test
autoAgents.supplier.username=test
autoAgents.supplier.secret=test
autoAgents.supplier.apiPassword=12345

autoAgents.client.id=1
autoAgents.client.name=test
autoAgents.client.serviceType=REST
autoAgents.client.authType=1
autoAgents.client.adapter=
autoAgents.client.username=test
autoAgents.client.secret=test
autoAgents.client.apiPassword=12345

Then I am injecting this values on the YAML, application.yml

activeProfile: ${activeProfile}

autoAgents:
    supplier:
        isSupplier: true
        meta:
            id: ${autoAgents.supplier.id}
            name: ${autoAgents.supplier.name}
            serviceType: ${autoAgents.supplier.serviceType}
            authType: ${autoAgents.supplier.authType}
            adapter: ${autoAgents.supplier.adapter}
        credentials:
            username: ${autoAgents.supplier.username}
            secret: ${autoAgents.supplier.secret}
            apiPassword: ${autoAgents.supplier.apiPassword}
    client:
    isSupplier: false
    meta:
        id: ${autoAgents.client.id}
        name: ${autoAgents.client.name}
        serviceType: ${autoAgents.client.serviceType}
        authType: ${autoAgents.client.authType}
        adapter: ${autoAgents.client.adapter}
    credentials:
        username: ${autoAgents.client.username}
        secret: ${autoAgents.client.secret}
        apiPassword: ${autoAgents.client.apiPassword}

And then I am importing this to a configuration property context:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties    
@Data
public class TwoConnectConfigurationProperties {
    
    private String activeProfile;
    @Value("${autoAgents.supplier}")
    private AutoAgentDup supplier;
    @Value("${autoAgents.client}")
    private AutoAgentDup client;
}

But @Value("${autoAgents.supplier}") is not working.

Please advise.

答案1

得分: 1

如前所述,向yaml注入值是没有意义的,你可以直接创建"application.yaml"文件并在其中添加值。然后删除".properties"文件。

你可能想要查看如何轻松地将具有共同后缀的属性注入到一个bean中。这里有一个很好的描述:
https://www.baeldung.com/configuration-properties-in-spring-boot

你将拥有一个bean:

@Configuration
@ConfigurationProperties(prefix = "autoAgents.supplier")
public class AutoAgentSupplierProperties {

  private long id;
  private String name;
  // ... 其他属性
}

你可能还想为"auto.agent"客户端创建相同的配置。

如果你想避免代码重复,你可以创建一个具有共同属性的bean。然后使用两个新类扩展该类,一个用于供应商,另一个用于代理,并在这些类上使用@ConfigurationProperties注解。

英文:

As mentioned earlier it does not make sense to inject values to yaml, you can just create the "application.yaml" with the values directly. And just delete the ".properies" file.

You might want to take a look how to easily inject the properties with common suffix into a bean. Its nicely described here:
https://www.baeldung.com/configuration-properties-in-spring-boot

You will have a bean:

@Configuration
@ConfigurationProperties(prefix = "autoAgents.supplier")
public class AutoAgentSupplierProperties {

  private long id;
  private String name;
  // ... rest of the properies properties
}

You might want the same for the "auto.agent" client.

If you want to avoid code duplication, you can have a bean with the common properties. Extend that class with 2 new classes. One for supplier and one for agent - and annotate those with

> @ConfigurationProperties

annotation.

答案2

得分: -1

为什么需要“嵌套属性”?如果只想在应用程序中访问它们,只需从.properties文件中获取值,并将其作为值填入.yml文件中。例如:profile: dev,或

autoAgents:
  client:
    id: 1

从.yml文件中获取属性的方式与从.properties文件中获取属性的方式相同。

您的问题在于您访问属性的方式。当您使用“@Configuration properties”时,您必须指定要使用哪一个(例如@ConfigurationProperties("autoAgents.client"))。

英文:

Why you need "nested properties"? If you only want to access them in application, just take values from .properties file and fill them as values to .yml file. E.g.: profile: dev, or

autoAgents:
  client:
    id: 1

Properties from .yml file can be accessed from code same way as from .properties file.

Your problem is in way how you access properties. When you use "@Configuration properties", you have to specific which one to use (e.g. @ConfigurationProperties("autoAgents.client").

huangapple
  • 本文由 发表于 2020年8月7日 20:37:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63302025.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定