【问题标题】:How do I use a variable from an application.yml file in my normal code?如何在我的普通代码中使用 application.yml 文件中的变量?
【发布时间】:2020-11-19 06:29:42
【问题描述】:

例如,假设在我的 yml 文件中有一个名为 indicator 的变量。并且基于指标变量的值是什么,我希望代码做一些不同的事情。如何访问常规代码中的 yml 变量并相应地使用它?

【问题讨论】:

标签: java spring spring-boot yaml


【解决方案1】:

你可以用这个:

@Value("${your.path.yml.string}")
private String x;

YML:

your:
  path:
    yml:
      string: hello

x 将是“你好”

【讨论】:

  • 哦,好的。当我尝试时,我得到一个错误,说通过字段'sampleService'表达的不满足的依赖关系;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“sampleServiceImpl”的 bean 时出错:注入自动装配的依赖项失败;嵌套异常是 java.lang.IllegalArgumentException:无法解析值“${indicator.string} 中的占位符“indicator.operation”
  • 在类中使用@Component。
  • 等待我使用它的类还是我必须为变量创建一个类?
  • 可能在你正在使用的类中
【解决方案2】:
  1. 你需要使用 Spring Expression Language 说我们应该写成
    @Value("${spring.application.name}") 
    private String appName;
  1. 如果 yaml/yml 或属性文件中不存在密钥,则为默认值
    @Value("${spring.application.name: defaultValue}") 
    private String appName;
  1. 获取值的最后一种方法是使用环境对象
    @Autowired  
    private Environment environment;
       
    String appName = environment.get("spring.application.name");

【讨论】:

    【解决方案3】:

    您可以将 @Value 注释添加到 bean 中的任何字段。

    @Value("$(path.to.your.variable)")
    String myString;
    

    也适用于构造函数。

    public MyClass(@Value("$(path.to.your.variable)") String myString) {
    

    【讨论】:

    • 路径会是什么样的?只是变量所在的yaml文件的路径?
    【解决方案4】:

    您可以在字段或参数上使用@Value 将属性分配给某个变量。

    属性示例:

    @Value("${indicator}")
    private String indicator
    

    参数示例:

    private void someMethod(@Value("${indicator}") String indicator) {
        ...
    }
    

    那么你就可以随心所欲地使用指标了。

    注意:你使用@Value的类应该是Spring Component

    【讨论】:

      【解决方案5】:

      使用 Spring-Boot,您可以自动为您提供文件 application.yml。你可以做的是在这个文件中添加一个属性,例如:

      my.properties: someValue
      

      然后,在您的一个 Spring Bean(使用 @Component@Bean 定义)中,您可以使用注释 @Value 检索此值。然后,对这个变量做任何你想做的事情。

      例如:

      @Component
      public class MyClass {
      
          @Value("${my.properties"}
          private String myProp; // will get "someValue" injected.
      
          ...
      
      
          // Just use it in a method
          public boolean myMethod() {
              if(myProp.equals("someValue") {
                  // do something
              } else {
                  // do something else
              } 
          }
      }
      

      【讨论】:

        【解决方案6】:

        做到这一点的最好方法是完全不要在 Spring 和您的“普通”代码之间进行紧密耦合,而是使用普通的 Java 功能,如构造函数以及 Spring @Bean 方法:

        class MyService {
            final String indicatorName;
        
            MyService(String indicatorName) {
                this.indicatorName = indicatorName;
            }
        }
        

        ...在您的配置类中...

        @Bean
        MyService myService(@Value("indicator.name") String indicatorName) {
            return new MyService(indicatorName);
        }
        

        特别针对 Spring Boot 的两个注意事项:

        • @ConfigurationProperties 功能允许您将属性映射到结构化 Java 数据类,并且通常比手动使用 @Value 更简洁。
        • 始终使用您自己定义的命名空间属性以避免将来与其他库发生冲突,因此请使用 company.project.indicator.name 代替 indicator.name。我建议在 Boot 中查看 DataSourceProperties 以查看如何设置所有这些的示例。

        不过,更广泛地说,当您说您希望代码“做一些不同的事情”时,听起来更好的选择可能是让 不同的类 在不同的情况下被激活。 Spring 配置文件和 Spring Boot 自动配置都有助于做到这一点。

        【讨论】:

          【解决方案7】:

          问题陈述可以重新定义为 Java 中的配置管理。

          您应该有一个像 ConfigManager 这样的组件,它会在您的应用程序启动时被实例化。该组件将读取一个属性文件,在您的用例中是一个 yaml。后续应用逻辑将从公开为简单键/值对的 Co​​nfigManager 中获取这些值。

          剩下的就是让您确定如何从 yaml 文件中读取和解析值。这已经在这里回答了: Parse a YAML file

          【讨论】:

          • 这整个功能是 Spring 首先提供的核心功能之一。
          • 问题中的任何地方都没有提到需要弹簧(尽管有标签)。我猜 - “对于一个拿着锤子的人来说,一切看起来都像钉子”:)
          • 它被标记为spring-boot,他提到了application.yml的名字。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-16
          • 2020-10-21
          • 1970-01-01
          • 2014-06-03
          • 2022-10-05
          • 2022-01-09
          相关资源
          最近更新 更多