Hướng dẫn nhanh về Spring @Value

1. Khái quát chung

Trong hướng dẫn nhanh này, chúng ta sẽ xem xét chú thích @Value Spring.

Chú thích này có thể được sử dụng để đưa các giá trị vào các trường trong các bean do Spring quản lý và nó có thể được áp dụng ở cấp trường hoặc cấp tham số phương thức / hàm tạo.

2. Thiết lập ứng dụng

Để mô tả các kiểu sử dụng khác nhau cho chú thích này, chúng ta cần cấu hình một lớp cấu hình ứng dụng Spring đơn giản.

Đương nhiên, chúng ta sẽ cần một tệp thuộc tính để xác định các giá trị mà chúng ta muốn đưa vào với chú thích @Value . Và vì vậy, trước tiên chúng ta cần xác định @PropertySource trong lớp cấu hình của chúng ta - với tên tệp thuộc tính.

Hãy xác định tệp thuộc tính:

value.from.file=Value got from the file priority=high listOfValues=A,B,C

3. Ví dụ sử dụng

Là một ví dụ cơ bản và hầu như vô dụng, chúng tôi chỉ có thể đưa "giá trị chuỗi" từ chú thích vào trường:

@Value("string value") private String stringValue;

Sử dụng chú thích @PropertySource cho phép chúng tôi làm việc với các giá trị từ tệp thuộc tính với chú thích @Value .

Trong ví dụ sau, chúng tôi nhận được Giá trị nhận được từ tệp được gán cho trường:

@Value("${value.from.file}") private String valueFromFile;

Chúng ta cũng có thể đặt giá trị từ các thuộc tính hệ thống với cùng một cú pháp.

Giả sử rằng chúng ta đã xác định thuộc tính hệ thống có tên systemValue :

@Value("${systemValue}") private String systemValue;

Giá trị mặc định có thể được cung cấp cho các thuộc tính có thể không được xác định. Tại đây, một số giá trị mặc định sẽ được đưa vào:

@Value("${unknown.param:some default}") private String someDefault;

Nếu cùng một thuộc tính được định nghĩa là thuộc tính hệ thống và trong tệp thuộc tính, thì thuộc tính hệ thống sẽ được áp dụng.

Giả sử chúng ta có mức ưu tiên thuộc tính được xác định là thuộc tính hệ thống với thuộc tính Hệ thống giá trị và được định nghĩa là thứ khác trong tệp thuộc tính. Giá trị sẽ là thuộc tính Hệ thống :

@Value("${priority}") private String prioritySystemProperty;

Đôi khi, chúng ta cần nhập một loạt các giá trị. Sẽ rất tiện lợi khi xác định chúng dưới dạng các giá trị được phân tách bằng dấu phẩy cho thuộc tính đơn lẻ trong tệp thuộc tính hoặc dưới dạng thuộc tính hệ thống và đưa vào một mảng.

Trong phần đầu tiên, chúng tôi đã xác định các giá trị được phân tách bằng dấu phẩy trong listOfValues của tệp thuộc tính , vì vậy các giá trị mảng sẽ là [“A”, “B”, “C”]:

@Value("${listOfValues}") private String[] valuesArray;

4. Ví dụ nâng cao với SpEL

Chúng ta cũng có thể sử dụng biểu thức SpEL để nhận giá trị.

Nếu chúng ta có thuộc tính hệ thống có tên là ưu tiên, thì giá trị của nó sẽ được áp dụng cho trường:

@Value("#{systemProperties['priority']}") private String spelValue;

Nếu chúng ta chưa xác định thuộc tính hệ thống, thì giá trị null sẽ được gán.

Để ngăn chặn điều này, chúng tôi có thể cung cấp một giá trị mặc định trong biểu thức SpEL. Chúng tôi nhận được một số giá trị mặc định cho trường nếu thuộc tính hệ thống không được xác định:

@Value("#{systemProperties['unknown'] ?: 'some default'}") private String spelSomeDefault;

Hơn nữa, chúng ta có thể sử dụng một giá trị trường từ các bean khác. Giả sử chúng ta có một bean có tên someBean với trường someValue bằng 10 . Sau đó, 10 sẽ được gán cho trường:

@Value("#{someBean.someValue}") private Integer someBeanValue;

Chúng ta có thể thao tác các thuộc tính để lấy Danh sách các giá trị, ở đây, danh sách các giá trị chuỗi A, B và C:

@Value("#{'${listOfValues}'.split(',')}") private List valuesList;

5. Sử dụng @Value với Maps

Chúng tôi cũng có thể sử dụng chú thích @Value để đưa thuộc tính Bản đồ vào .

Đầu tiên, chúng tôi cần xác định thuộc tính trong biểu mẫu {key: 'value'} trong tệp thuộc tính của chúng tôi:

valuesMap={key1: '1', key2: '2', key3: '3'}

Lưu ý rằng các giá trị trong Bản đồ phải nằm trong dấu nháy đơn.

Bây giờ chúng ta có thể đưa giá trị này từ tệp thuộc tính dưới dạng Bản đồ :

@Value("#{${valuesMap}}") private Map valuesMap;

Nếu chúng ta cần lấy giá trị của một khóa cụ thể trong Bản đồ , tất cả những gì chúng ta phải làm là thêm tên của khóa đó vào biểu thức :

@Value("#{${valuesMap}.key1}") private Integer valuesMapKey1;

Nếu chúng tôi không chắc liệu Bản đồ có chứa một khóa nhất định hay không, chúng tôi nên chọn một biểu thức an toàn hơn sẽ không đưa ra ngoại lệ nhưng đặt giá trị thành null khi không tìm thấy khóa:

@Value("#{${valuesMap}['unknownKey']}") private Integer unknownMapKey;

Chúng tôi cũng có thể đặt giá trị mặc định cho các thuộc tính hoặc khóa có thể không tồn tại :

@Value("#{${unknownMap : {key1: '1', key2: '2'}}}") private Map unknownMap; @Value("#{${valuesMap}['unknownKey'] ?: 5}") private Integer unknownMapKeyWithDefaultValue;

Các mục bản đồ cũng có thể được lọc trước khi tiêm.

Giả sử chúng ta chỉ cần lấy những mục nhập có giá trị lớn hơn một:

@Value("#{${valuesMap}.?[value>'1']}") private Map valuesMapFiltered;

Chúng tôi cũng có thể sử dụng chú thích @Value để đưa vào tất cả các thuộc tính hệ thống hiện tại :

@Value("#{systemProperties}") private Map systemPropertiesMap;

6. Sử dụng @Value với Constructor Injection

When we use the @Value annotation, we're not limited to a field injection. We can also use it together with constructor injection.

Let's see this in practice:

@Component @PropertySource("classpath:values.properties") public class PriorityProvider { private String priority; @Autowired public PriorityProvider(@Value("${priority:normal}") String priority) { this.priority = priority; } // standard getter }

In the above example, we inject a priority directly into our PriorityProvider‘s constructor.

Note that we also provide a default value in case the property isn't found.

7. Using @Value With Setter Injection

Analogous to the constructor injection, we can also use @Value with setter injection.

Let's take a look:

@Component @PropertySource("classpath:values.properties") public class CollectionProvider { private List values = new ArrayList(); @Autowired public void setValues(@Value("#{'${listOfValues}'.split(',')}") List values) { this.values.addAll(values); } // standard getter }

We use the SpEL expression to inject a list of values into the setValues method.

8. Conclusion

Trong bài viết này, chúng tôi đã xem xét các khả năng khác nhau của việc sử dụng chú thích @Value với các thuộc tính đơn giản được xác định trong tệp, với các thuộc tính hệ thống và với các thuộc tính được tính bằng biểu thức SpEL.

Như mọi khi, ứng dụng mẫu có sẵn trên dự án GitHub.