简体   繁体   中英

How do I use a variable from an application.yml file in my normal code?

For example, let's say that in my yml file I had a variable called indicator. And based on what the indicator variable's value was I want the code to do something different. How would I access the yml variable in the regular code and use it accordingly?

You can use this:

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

YML:

your:
  path:
    yml:
      string: hello

x will be "hello"

  1. You need to use Spring Expression Language which says we should write it as
    @Value("${spring.application.name}") 
    private String appName;
  1. For Default value if key is not present in yaml/yml or properties file
    @Value("${spring.application.name: defaultValue}") 
    private String appName;
  1. The last way you can fetch value is using environment object
    @Autowired  
    private Environment environment;
       
    String appName = environment.get("spring.application.name");

You can add @Value annotation to any field in your beans.

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

Works with constructors as well.

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

You can use @Value on fields or parameters to assign the property to some variable.

Property example:

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

Parameter example:

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

Then you can use indicator as you want.

Note: the class where you use @Value should be a Spring Component

With Spring-Boot, you have the file application.yml automatically provided for you. What you can do is adding a property in this file, for instance:

my.properties: someValue

Then, in one of your Spring Bean (either define with @Component or @Bean ) you can retrieve this value using the annotation @Value . Then, do whatever you want with this variable.

For instance:

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

The best way to do this is not to have a tight coupling between Spring and your "normal" code at all, but instead to use the normal Java features like constructors along with Spring @Bean methods:

class MyService {
    final String indicatorName;

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

... in your configuration class...

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

Two notes for Spring Boot specifically:

  • The @ConfigurationProperties feature allows you to map properties onto structured Java data classes and is typically cleaner than using @Value by hand.
  • Always namespace properties that you define yourself to avoid future collisions with other libraries, so instead of indicator.name use company.project.indicator.name . I recommend looking at DataSourceProperties in Boot to see an example of how to set all this up.

More broadly, though, when you say that you want the code to "do something different", it sounds like the better option might be to have different classes that get activated under different circumstances. Both Spring profiles and Spring Boot auto-configuration help to do this.

The problem statement can be re-defined as Configuration Management in Java.

You should have a component like ConfigManager that gets instantiated as part of your application start up. That component will read a properties file, a yaml in your use case. Subsequent app logic will fetch these values from the ConfigManager exposed as simple key/value pairs.

All that is left for you to identify how to read and parse values from yaml file. This is already answered here: Parse a YAML file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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