Unlock the Full Power of Spring’s @Value: Tips, Tricks, and Hidden Features

This comprehensive guide explores Spring's @Value annotation, covering basic usage, property name handling, encoding issues, default values, static fields, various data types, collection injection, EL expressions, bean injection, and the differences between ${} and #{} to help Java developers master configuration injection.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Unlock the Full Power of Spring’s @Value: Tips, Tricks, and Hidden Features

Introduction

For Java developers, the Spring framework is familiar, offering rich APIs such as @Controller, @Service, @Repository, @Component for bean creation, @Autowired and @Resource for dependency injection, @Transactional for transaction management, and @Value for reading configuration properties.

This article focuses on the often‑overlooked @Value annotation, which many developers only use partially.

1. A Simple Example

Inject a system property into a field:

@Service
public class UserService {
    @Value("${susan.test.userName}")
    private String userName;

    public String test() {
        System.out.println(userName);
        return userName;
    }
}

The property name must be wrapped in ${} and defined in applicationContext.properties:

#example
susan.test.userName=\u5f20\u4e09

2. Property Name Matching

When using @ConfigurationProperties, the field name can differ from the property name as long as the prefix matches. However, with @Value the property name must be identical; otherwise the application fails to start.

@Value annotation requires the property name to match exactly.

3. Encoding Issues

Chinese characters in .properties files are often escaped (e.g., \u5f20\u4e09). If not escaped, Spring’s CharacterReader reads the file using ISO‑8859‑1, causing garbled output.

Solutions:

Manually convert ISO‑8859‑1 to UTF‑8.

Set an encoding parameter (only works with @PropertySource, not @Value).

Use Unicode escape sequences.

Example of manual conversion:

@Service
public class UserService {
    @Value(value = "${susan.test.userName}")
    private String userName;

    public String test() {
        String userName1 = new String(userName.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        System.out.println();
        return userName1;
    }
}

4. Default Values

Provide a default using a colon:

@Value(value = "${susan.test.userName:susan}")
private String userName;

If the property is missing, the default is injected. An empty default can be set with :"".

5. Static Variables

Static fields cannot be injected directly with @Value. Use a setter method annotated with @Value to assign the static variable:

@Service
public class UserService {
    private static String userName;

    @Value("${susan.test.userName}")
    public void setUserName(String userName) {
        UserService.userName = userName;
    }
}

6. Variable Types

6.1 Primitive Types

@Value supports all Java primitive types and their wrapper classes:

@Value("${susan.test.a:1}")
private byte a;

@Value("${susan.test.g:false}")
private boolean g;

@Value("${susan.test.h:h}")
private char h;

6.2 Arrays

Inject an array using comma‑separated values:

@Value("${susan.test.array:1,2,3,4,5}")
private int[] array;

Spaces are removed, so ${susan.test.array:1 2 3} becomes a single value 123.

6.3 Collections

List

Inject a List via EL expression:

@Value("#{'${susan.test.list}'.split(',')}")
private List<String> list;

Configuration example:

susan.test.list=10,11,12,13

Set

Similar to List, but ensure an empty Set returns null using the empty check:

@Value("#{'${susan.test.set:}'.empty ? null : '${susan.test.set:}'.split(',')}")
private Set<String> set;

Map

Inject a Map with EL:

@Value("#{${susan.test.map}}")
private Map<String, String> map;

Configuration example:

susan.test.map={"name":"苏三", "age":"18"}

7. Advanced EL Usage

7.1 Bean Injection

Inject a bean directly:

@Value("#{roleService}")
private RoleService roleService;

7.2 Accessing Bean Members

Inject fields, constants, methods, and static methods:

@Value("#{roleService.DEFAULT_AGE}")
private int myAge;

@Value("#{roleService.id}")
private int id;

@Value("#{roleService.getRoleName()}")
private String myRoleName;

@Value("#{roleService.getParentId()}")
private String myParentId;

7.3 Static Classes

Use T() to access static members:

@Value("#{T(java.io.File).separator}")
private String path;

@Value("#{T(java.lang.Math).random()}")
private double randomValue;

7.4 Logical Operations

Combine values, perform conditional checks, and ternary operations inside EL:

@Value("#{roleService.DEFAULT_AGE > 16 and roleService.roleName.equals('苏三')}")
private String operation;

@Value("#{roleService.DEFAULT_AGE > 16 ? roleService.roleName : '苏三'}")
private String realRoleName;

8. Difference Between ${} and #{}

${}

retrieves configuration properties and supports default values via :. #{} evaluates Spring EL expressions, allowing bean property access, method invocation, static member access, and complex logic.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Configurationspringdependency-injection@ValueEL expression
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

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.