Inject Properties from Properties File using @Value Annotation

This tutorial shows you the way to inject Properties from Properties File using @Value Annotation with Java Configuration and @PropertySource.

You will also know how to use SourcesPlaceHolder and ConversionService for specific cases including: List/Arrays, special types (DateTime, Pattern), when a value that should be treated as null or a placeholder fails to resolve.

I. Technology

– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.1.RELEASE (It’s OK if you use Eclipse)

II. Overview

1. Project Structure

springproperties-structure

2. Step to do

– Create Maven project
– Add Dependencies & Plugins
– Add Properties Files
– Create a Service
– Create Configuration Class
– Create MainApplication Class
– Run Application & Enjoy Result

III. Practice

1. Create Maven project

– Open Spring Tool Suite, on Menu, choose File -> New -> Maven Project.
– Check Create a simple project, choose Workspace Location and click Next.
– Fill all fields in Artifact group box, then click Finish.

2. Add Dependencies & Plugins

Open pom.xml, add:

<properties>
	<java-version>1.8</java-version>
	<org.springframework-version>4.3.2.RELEASE</org.springframework-version>
</properties>

<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>${org.springframework-version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${org.springframework-version}</version>
	</dependency>
</dependencies>

<build>
	<pluginManagement>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.3</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</pluginManagement>
</build>

3. Add Properties Files

Under src/main/resources, add these properties files:

myapp.properties


#config.string.keyUnresolvable=unresolvable
config.string.key=stringValue
config.string.keyNull=This is NULL
config.int.key=1886
config.boolean.key=true

myapp2.properties


config.intList.key=1,2,3,4,5
config.stringList.key=one,two,three,four,five

myapp3.properties


config.time.key=16/09/30 06:45
config.pattern.key=[0-9].[0-9].*

4. Create a Service

Under package service, create interface for Service and implementation of that interface.

IService.java


package com.javasampleapproach.springproperties.service;

public interface IService {
	public String getValue();
}

MyService.java


package com.javasampleapproach.springproperties.service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;

@Service("service")
public class MyService implements IService {

	@Value("${config.string.keyUnresolvable}")
	private String stringKeyUnresolvable;

	@Value("${config.string.key}")
	private String stringKey;

	// treated as null
	@Value("${config.string.keyNull}")
	private String stringKeyNull;

	@Value("${config.int.key}")
	private int intKey;

	// not define in properties file
	@Value("${config.int.keyDefault:2016}")
	private int intKeyDefault;

	@Value("${config.boolean.key}")
	private boolean boolKey;

	@Value("${config.intList.key}")
	private List intList;

	@Value("${config.stringList.key}")
	private List stringList;

	@DateTimeFormat(pattern="yy/MM/dd HH:mm")
	@Value("${config.time.key}")
	private LocalDateTime time;
	
	@Value("${config.pattern.key}")
	private Pattern pattern;

	@Override
	public String getValue() {
		String result = "Properties Values from Configuration File:\n";

		result += "- stringKeyUnresolvable: " + stringKeyUnresolvable + "\n";
		result += "- stringKey: " + stringKey + "\n";
		result += "- stringKeyNull: " + stringKeyNull + "\n";
		result += "- intKey: " + intKey + "\n";
		result += "- intKeyDefault: " + intKeyDefault + "\n";
		result += "- boolKey: " + boolKey + "\n";
		result += "- intList: " + intList + "\n";
		result += "- stringList: " + stringList + "\n";
		result += "- time: " + time + "\n";
		result += "- pattern: " + pattern + "\n";

		return result;
	}
}

5. Create Configuration Class

Under package config, create AppConfig.java:


package com.javasampleapproach.springproperties.config;

import java.util.regex.Pattern;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.support.DefaultFormattingConversionService;

@Configuration
@ComponentScan(basePackages = "com.javasampleapproach.springproperties")
@PropertySource(value={"classpath:myapp.properties","classpath:myapp2.properties","classpath:myapp3.properties"})
public class AppConfig {
	
	@Bean
	public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
//		return new PropertySourcesPlaceholderConfigurer();
		
		PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
//		configurer.setLocation(new ClassPathResource("myapp.properties"));
		
		configurer.setIgnoreUnresolvablePlaceholders(true);
		configurer.setNullValue("This is NULL");
		
		return configurer;
	}
	
	@Bean
	public static ConversionService conversionService() {
//		return new DefaultFormattingConversionService();
		
		DefaultFormattingConversionService cs = new DefaultFormattingConversionService();

		cs.addConverter(String.class, Pattern.class, (Converter) Pattern::compile);
		
		return cs;
	}
}

– Because we don’t use XML Configuration File to define Beans, so @ComponentScan is necessary.

@PropertySource(value={String Array Paths}): adds property sources to the environment.
*Note: If there is a property key that exists in 2 or more files, when injecting using @Value, the value of the key in the last file is chosen.

PropertySourcesPlaceHolderConfigurer Bean is vital Bean for using @Value(“{…}”) annotations. Remove it if not using @Value for injecting properties.
+ setLocation: set location for properties file to be loaded, not necessary if we have used @PropertySource before.
+ if we setIgnoreUnresolvablePlaceholders by true, in case that placeholder fails to resolve, a String of Value Expression will be returned instead.
In our example, because there is no property with key config.string.keyUnresolvable, the system will show:


stringKeyUnresolvable: ${config.string.keyUnresolvable} 

+ setNullValue(thing-will-be-NULL): set a value that should be treated as null. This is the way to express null as a property value.
*Note: only apply to full property values, not to parts of them.

ConversionService Bean is used to inject more complex property types as List/Array, DateTime… We can use addConverter to register a Converter. Our example will convert a string to a regular expression object Pattern.


config.pattern.key=[0-9].[0-9].*

6. Create MainApplication Class

MainApp.java


package com.javasampleapproach.springproperties;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;

import com.javasampleapproach.springproperties.config.AppConfig;
import com.javasampleapproach.springproperties.service.IService;

public class MainApp {

	public static void main(String[] args) {
		AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		
		IService service = (IService) context.getBean("service");
		System.out.println(service.getValue());
		
		context.close();
	}
}

7. Run Application & Enjoy Result

– Config maven build:
clean install
– Run project with mode Java Application
– Check results in Console Screen:


Properties Values from Configuration File:
- stringKeyUnresolvable: ${config.string.keyUnresolvable}
- stringKey: stringValue
- stringKeyNull: null
- intKey: 1886
- intKeyDefault: 2016
- boolKey: true
- intList: [1, 2, 3, 4, 5]
- stringList: [one, two, three, four, five]
- time: 2016-09-30T06:45
- pattern: [0-9].[0-9].*

IV. Source Code

springproperties

2 thoughts on “Inject Properties from Properties File using @Value Annotation”

  1. I抦 not sure where you’re getting your information, but great topic. I needs to spend some time learning much more or understanding more. Thanks for excellent information I was looking for this info for my mission.

Leave a Reply

Your email address will not be published. Required fields are marked *