Trong bài viết này, mình sẽ giới thiệu với các bạn làm cách nào để sử dụng properties trong Spring với annotation @Value các bạn nhé!
Đầu tiên, mình sẽ tạo mới một Maven project để làm ví dụ:
Mình sẽ sử dụng Java 17 cho ví dụ này:
1 2 3 4 |
<properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> |
Spring framework dependency:
1 2 3 4 5 |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.0.3</version> </dependency> |
Class HelloWorld:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.huongdanjava.springvalueannotation; public class HelloWorld { private String name; public void print() { System.out.print("Hello " + name); } public String getName() { return name; } public void setName(String name) { this.name = name; } } |
Class Application:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.huongdanjava.springvalueannotation; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Application { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld"); helloWorld.print(); } } |
configuration.properties
1 |
name=Khanh |
spring.xml
1 2 3 4 5 6 7 8 9 |
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:property-placeholder location="classpath:configuration.properties" /> </beans> |
Để sử dụng properties với @Value annotation, chúng ta cần khai báo các bean trong Spring sử dụng các annotation như: @Component, @Service, @Repository, @Controller,…
Trong ví dụ này, mình muốn khai báo đối tượng HelloWorld trong khung chứa của Spring và sử dụng @Value annotation để gán giá trị cho thuộc tính name của đối tượng HelloWorld này bằng giá trị của property name trong tập tin configuration.properties thì mình sẽ làm như sau:
Đầu tiên, mình sẽ khai báo thẻ context:component-scan trong tập tin spring.xml để enable khả năng auto component scan trong Spring cho package com.huongdanjava.springvalueanntation:
1 |
<context:component-scan base-package="com.huongdanjava.springvalueannotation" /> |
Cái thứ hai mình sẽ khai báo @Component annotation bên trong class HelloWorld để khởi tạo bean HelloWorld trong khung chứa của Spring:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package com.huongdanjava.springvalueannotation; import org.springframework.stereotype.Component; @Component public class HelloWorld { private String name; public void print() { System.out.print("Hello " + name); } public String getName() { return name; } public void setName(String name) { this.name = name; } } |
Cuối cùng, mình sẽ sử dụng @Value annotation để ingest giá trị của property name trong tập tin configuration.properties vào thuộc tính name trong đối tượng HelloWorld như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.huongdanjava.springvalueannotation; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class HelloWorld { @Value("${name}") private String name; public void print() { System.out.print("Hello " + name); } public String getName() { return name; } public void setName(String name) { this.name = name; } } |
Ở đây, mình đã khai báo @Value annotation với giá trị là ${property_name}.
Kết quả:
Trong trường hợp, property name không tồn tại, lỗi sau sẽ xuất hiện khi chúng ta chạy ứng dụng lên:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloWorld': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'name1' in value "${name1}" at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) at com.huongdanjava.springvalueannotation.Application.main(Application.java:9) Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'name1' in value "${name1}" at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174) at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:236) at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:172) at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:831) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1086) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ... 13 more |
Để tránh lỗi này, trong trường hợp property name không tồn tại, chúng ta có thể thay thế bằng giá trị mặc định bằng cách khai báo @Value annotation như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.huongdanjava.springvalueannotation; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class HelloWorld { @Value("${name1:Huong Dan Java}") private String name; public void print() { System.out.print("Hello " + name); } public String getName() { return name; } public void setName(String name) { this.name = name; } } |
Kết quả:
Đào tuyên
chỗ context.getBean(“helloWorld”); cái từ helloWord nó mapping với thằng nào vậy anh. em xem trong spring.xml không thấy cái bean nào có id như vậy và của em nó báo lỗi không tìm thấy cái bean nào có id là ‘helloWorld’.
Khanh Nguyen
Nó là tên class với ký tự đầu được viết thường đó bạn! Bạn đọc thêm ở đây nhé https://huongdanjava.com/vi/auto-component-scan-trong-spring.html
Tan
anh có thể viết một bài nói rõ về các annotions thường dùng trong Spring boot or Spring đc ko ạ
Han Anh
Anh ơi cho em xin source code bài này tham khảo với. có 1 số cái em chưa nắm ro94
Khanh Nguyen
Xem ở đây nhé em https://github.com/huongdanjavacom/huongdanjava.com/tree/master/spring-value-annotation
Tất cả các ví dụ của Hướng Dẫn Java anh đều commit lên GitHub.