DEV Community

Willian Ferreira Moya
Willian Ferreira Moya

Posted on • Originally published at springmasteryhub.com

12 Ways to Use the @Value Annotation in Spring for Flexible and Maintainable Applications

You may already be familiar with @Value annotation from Spring. This annotation allows you to inject some properties into your beans.

But there’s a lot of ways you could do that. And maybe you are not familiar with all of them.

This article will show you many ways to work with @Value and some new ways you can apply to your projects.

Let’s explore our options!

1. Basic property injection

This is the most used option in Spring projects. It’s the common way you can control feature flags, API keys, database connection details, etc.

Example:

@Value("${feature.enableDarkMode}")
private boolean isDarkModeEnabled;
Enter fullscreen mode Exit fullscreen mode

Properties:

feature.enableDarkMode=true
Enter fullscreen mode Exit fullscreen mode

2. Hardcoded Values:

This way set the value as a constant in your code, this way you cannot change it externally.

@Value("localhost")
private String defaultServerAddress;
Enter fullscreen mode Exit fullscreen mode

3. Constructor Injection

Here is to create immutable beans that need their dependencies and values upfront.

Example:

public TestBean(@Value("${mail.smtp.server}") String smtpServer) {
    this.smtpServer = smtpServer;
}

Enter fullscreen mode Exit fullscreen mode

Properties:

mail.smtp.server=smtp.example.com
Enter fullscreen mode Exit fullscreen mode

4. SetUp Default Values:

You can provide default values when injecting your properties to avoid application crashes. If you do not have the property set, it will automatically pick the default value.

Example:

@Value("${app.cache.ttl:60}")  // Default TTL of 60 seconds if not configured
private int cacheTimeToLive;
Enter fullscreen mode Exit fullscreen mode

5. Inject Using Set Method (Less common)

This is an option in some legacy code bases, where construction is not possible, this way of injection becomes an option.

Example:

@Value("${log.level}")
public void setLogLevel(String logLevel) {
    this.logLevel = logLevel;
}
Enter fullscreen mode Exit fullscreen mode

Properties:

log.level=INFO
Enter fullscreen mode Exit fullscreen mode

6. Injecting an Array of values:

You can set an array of values, using comma-separated values, Spring will automatically split values and put them in the array positions. You can use this to set an array of allowed origins configured by properties.

Example:

@Value("${cors.allowedOrigins}")
private String[] allowedOrigins;
Enter fullscreen mode Exit fullscreen mode

Properties:

cors.allowedOrigins=https://example1.com,https://example2.com
Enter fullscreen mode Exit fullscreen mode

7. Injecting a List of Values:

If you want more flexibility in your Java code, injecting a collection of values you can use SpEL to split values to create the list.

Example:

@Value("#{'${notification.channels}'.split(',')}")
private List<String> notificationChannels;
Enter fullscreen mode Exit fullscreen mode

Properties:

notification.channels=EMAIL,SMS,PUSH
Enter fullscreen mode Exit fullscreen mode

8. Inject Maps

You can inject in a Java map a group of configurations that uses key-value pattern.

Example:

@Value("#{${http.client.config}}")
private Map<String, Integer> httpClientConfig;

Enter fullscreen mode Exit fullscreen mode

Properties:

http.client.config={timeout: 500, maxConnections: 100}
Enter fullscreen mode Exit fullscreen mode

9. Inject a Single Value From a Map

In the same way, you can inject an entire map of values, you can use SpEL to inject a single value using its key.

Example:

@Value("#{${http.client.config}['timeout']}")
private int timeout;
Enter fullscreen mode Exit fullscreen mode

Properties:

http.client.config={timeout: 500, maxConnections: 100}
Enter fullscreen mode Exit fullscreen mode

10. Access System Properties

This method will allow you to get the system properties from the Java properties, also it gets all the properties that you set when running the application with the -D parameter.

Example:

@Value("#{systemProperties['java.home']}")
private String javaHome;
Enter fullscreen mode Exit fullscreen mode

In this example, the java.home is already passed automatically to the process. But if you want to access some custom property you can do this:

@Value("#{systemProperties['custom.property']}")
private String javaHome;
Enter fullscreen mode Exit fullscreen mode

Running the project with custom property:

java -Dcustom.property="value" -jar app.jar
Enter fullscreen mode Exit fullscreen mode

11. Get Environment Variables:

You can read an environment variable from your system (if the application has access to the variable).

Example:

@Value("#{environment['MY_ENV_VAR']}")
private String myEnvVar;
Enter fullscreen mode Exit fullscreen mode

12. Use SpEL and Create Dynamic Properties

One common problem developers have is that the team members can be working on different OS, so you can create a dynamic property based on the system to make things more flexible.

Example:

@Value("#{systemProperties['os.name'].toLowerCase().contains('windows') ? 'C:\\' : '/'}")
private String rootDirectory;
Enter fullscreen mode Exit fullscreen mode

This will get the os.name from the system and decide what is the root directory to inject the value.

That’s it! Now you have a whole set of new ways to configure your Spring applications with @Value!

That will give you more flexibility and options. It will offer a solution that fills your needs. By understanding how it works you can write more maintainable Spring applications.

Test out new ways of Injecting properties into your project!

If you like this topic, make sure to follow me, in the following days, I’ll be explaining more about the Spring annotations!

Stay tuned!

References

  1. Baeldung: Spring @Value Annotation
  2. Spring Framework Documentation: @Value Annotations
  3. DigitalOcean: Spring @Value Annotation

Top comments (0)