In this tutorial, I would like to introduce to you all how to use properties in Spring with @Value annotation.
First of all, we need a Maven project for example:
I will use Java 17 for this example:
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> |
HelloWorld class:
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; } } |
Application class:
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> |
To use properties with @Value annotation, we need to declare bean in Spring using annotations such as @Component, @Service, @Repository, @Controller, …
In this example, I want to declare the HelloWorld object in the Spring container and use the @Value annotation to assign the value of the name property in the HelloWorld object equal to the value of the property name in the configuration.properties file then I will do as follows:
First, I will declare tag context:component-scan in spring.xml file to enable auto component scan in Spring for package com.huongdanjava.springvalueanntation:
1 |
<context:component-scan base-package="com.huongdanjava.springvalueannotation" /> |
After that, I will declare @Component in class HelloWorld to initialize the HelloWorld bean in the Spring container:
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; } } |
Finally, I will use @Value annotation to ingest the value of the property name in configuration.properties into the name property in the HelloWorld object as below:
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; } } |
Here, I have declared @Value annotation with the value $ {property_name}.
Result:
In case the property name does not exist, the following error is encountered when running:
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 |
To avoid this error, in case the property name does not exist, we can substitute the default value by declaring the @Value annotation as follows:
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; } } |
Result: