Backend Development 8 min read

Mastering Spring @Value: From Basics to Advanced Techniques

This article explains how Spring Boot’s @Value annotation injects configuration values, covers basic usage, default values, nested properties, SpEL expressions, custom type converters, placeholder handling, custom meta‑annotations, and combining property placeholders for dynamic URLs, providing complete code examples.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Spring @Value: From Basics to Advanced Techniques

1. Introduction

Spring's @Value annotation injects external configuration (e.g., from application.yml ) into bean fields, constructor parameters, or method parameters. It supports simple types, SpEL expressions, and default values, making it a convenient choice for straightforward configuration needs.

<code>@Value("${pack.title}")
private String title ;
</code>

Corresponding YAML:

<code>pack:
  title: xxxooo
</code>

The above assigns title the value xxxooo . Type conversion is automatic, e.g., to LocalDate :

<code>@Value("${pack.date}")
private LocalDate date ;
</code>
<code>pack:
  date: 2024-07-27
</code>

2. Advanced Usage

2.1 Default Value

If a property is missing, Spring Boot throws an exception. You can provide a default by appending a colon:

<code>@Value("${pack.version:}")
</code>

or with an actual fallback value:

<code>@Value("${pack.version:1.0.0}")
</code>

2.2 Nested Property

You can reference another property inside the default expression:

<code>@Value("${pack.title:${title}}")
private String title ;
</code>

YAML example:

<code>title: xxxooo
pack:
  date: 2024-07-27
</code>

2.3 Using SpEL Expressions

Inject system properties:

<code>@Value("#{systemProperties['java.home']}")
private String javaHome ;
</code>

Result example:

<code>D:\devsoft\jdk-21_windows-x64_bin\jdk-21.0.1</code>

Inject other beans:

<code>@RestController
public class UserController {
  @Value("#{us}")
  private UserService us ;

  @Override
  public String toString() {
    return "UserController [us=" + us + "]";
  }
}
</code>

Result:

<code>com.pack.UserService@54e1c68b</code>

2.4 Custom Type Conversion

Register a custom converter:

<code>@Bean
public ConversionService conversionService() {
    DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
    conversionService.addConverter(new StringToDateConverter());
    return conversionService;
}
public class StringToDateConverter implements Converter<String, Date> {
  public Date convert(String source) {
    try {
      return new SimpleDateFormat("yyyy-MM-dd").parse(source);
    } catch (ParseException e) {
      throw new RuntimeException(e);
    }
  }
}
</code>

Then:

<code>@Value("${pack.date}")
private Date productDate ;
</code>

Result:

<code>Sat Jul 27 00:00:00 CST 2024</code>

Note: In Spring Boot, using BeanFactoryPostProcessor is often recommended for such registrations.

2.5 Custom Default Behavior

Override placeholder handling to ignore unresolved placeholders:

<code>@Bean
public PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
  PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
  pspc.setIgnoreUnresolvablePlaceholders(true);
  return pspc;
}
</code>

When the property is absent, the expression itself is output:

<code>@Value("${pack.version}")
private String version ;
</code>
<code>${pack.version}</code>

You can also change the placeholder delimiters:

<code>pspc.setPlaceholderPrefix("&{");
pspc.setPlaceholderSuffix("}");
</code>

2.6 Custom @Value Annotation

Create a meta‑annotation to reuse a specific property key:

<code>@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Value("${pack.url}")
public @interface PackValue {}
</code>

Usage:

<code>@PackValue
private String url ;
</code>

2.7 Combining ${} and #{}

Compose a value from multiple properties using SpEL:

<code>@Value("#{'${pack.baseURL}' + '/api/v' + '${app.version}'}")
private String url ;
</code>

YAML:

<code>app:
  version: 1.0
pack:
  baseURL: https://www.pack.com
</code>

Result:

<code>http://www.pack.com/api/v1.0</code>
JavaconfigurationSPELSpring Boot@Value
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.