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

RMAG news

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;

Properties:

feature.enableDarkMode=true

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;

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

Properties:

mail.smtp.server=smtp.example.com

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;

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

Properties:

log.level=INFO

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;

Properties:

cors.allowedOrigins=https://example1.com,https://example2.com

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;

Properties:

notification.channels=EMAIL,SMS,PUSH

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;

Properties:

http.client.config={timeout: 500, maxConnections: 100}

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;

Properties:

http.client.config={timeout: 500, maxConnections: 100}

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;

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;

Running the project with custom property:

java Dcustom.property=“value” jar app.jar

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;

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;

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

Baeldung: Spring @Value Annotation
Spring Framework Documentation: @Value Annotations
DigitalOcean: Spring @Value Annotation