Reputation: 12621
I am using spring. I need to read values from properties file. This is internal properties file not the external properties file. Properties file can be as below.
some.properties ---file name. values are below.
abc = abc
def = dsd
ghi = weds
jil = sdd
I need to read those values from the properties file not in traditional way. How to achieve it? Is there any latest approach with spring 3.0?
Upvotes: 149
Views: 569299
Reputation: 5632
In Spring Boot version 3; Create a file like this : GlobalProperties.java
package com.tester.trader.config;
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties
@PropertySource({"classpath:global.properties"})
@Data
@ToString
public class GlobalProperties {
private String loginUrl;
private String symbolsUrl;
}
Add file global.properties to your resources folder beside the application.properies and paste the following
symbolsUrl=https://api.market-stage.test.com/market/symbol-thumb
loginUrl="https://api.test.com/api/sign-in"
Now you can @Autowired in every service like this:
@Autowired
GlobalProperties globalProperties;
public String readIt(){
return globalProperties.getSymbolsUrl()
}
Upvotes: 0
Reputation: 12880
Configure PropertyPlaceholder in your context:
<context:property-placeholder location="classpath*:my.properties"/>
Then you refer to the properties in your beans:
@Component
class MyClass {
@Value("${my.property.name}")
private String[] myValues;
}
To parse property with multiple comma-separated values:
my.property.name=aaa,bbb,ccc
If that doesn't work, you can define a bean with properties, inject and process it manually:
<bean id="myProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath*:my.properties</value>
</list>
</property>
</bean>
and the bean:
@Component
class MyClass {
@Resource(name="myProperties")
private Properties myProperties;
@PostConstruct
public void init() {
// do whatever you need with properties
}
}
Upvotes: 211
Reputation: 3715
I wanted an utility class which is not managed by spring, so no spring annotations like @Component
, @Configuration
etc. But I wanted the class to read from application.properties
I managed to get it working by getting the class to be aware of the Spring Context, hence is aware of Environment
, and hence environment.getProperty()
works as expected.
To be explicit, I have:
application.properties
mypath=somestring
Utils.java
import org.springframework.core.env.Environment;
// No spring annotations here
public class Utils {
public String execute(String cmd) {
// Making the class Spring context aware
ApplicationContextProvider appContext = new ApplicationContextProvider();
Environment env = appContext.getApplicationContext().getEnvironment();
// env.getProperty() works!!!
System.out.println(env.getProperty("mypath"))
}
}
ApplicationContextProvider.java (see Spring get current ApplicationContext)
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext CONTEXT;
public ApplicationContext getApplicationContext() {
return CONTEXT;
}
public void setApplicationContext(ApplicationContext context) throws BeansException {
CONTEXT = context;
}
public static Object getBean(String beanName) {
return CONTEXT.getBean(beanName);
}
}
Upvotes: 2
Reputation:
There are various ways to achieve the same. Below are some commonly used ways in spring-
Using PropertyPlaceholderConfigurer
Using PropertySource
Using ResourceBundleMessageSource
Using PropertiesFactoryBean
and many more........................
Assuming ds.type
is key in your property file.
Using PropertyPlaceholderConfigurer
Register PropertyPlaceholderConfigurer
bean-
<context:property-placeholder location="classpath:path/filename.properties"/>
or
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:path/filename.properties" ></property>
</bean>
or
@Configuration
public class SampleConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
//set locations as well.
}
}
After registering PropertySourcesPlaceholderConfigurer
, you can access the value-
@Value("${ds.type}")private String attr;
Using PropertySource
In the latest spring version you don't need to register PropertyPlaceHolderConfigurer
with @PropertySource
, I found a good link to understand version compatibility-
@PropertySource("classpath:path/filename.properties")
@Component
public class BeanTester {
@Autowired Environment environment;
public void execute() {
String attr = this.environment.getProperty("ds.type");
}
}
Using ResourceBundleMessageSource
Register Bean-
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:path/filename.properties</value>
</list>
</property>
</bean>
Access Value-
((ApplicationContext)context).getMessage("ds.type", null, null);
or
@Component
public class BeanTester {
@Autowired MessageSource messageSource;
public void execute() {
String attr = this.messageSource.getMessage("ds.type", null, null);
}
}
Using PropertiesFactoryBean
Register Bean-
<bean id="properties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:path/filename.properties</value>
</list>
</property>
</bean>
Wire Properties instance into your class-
@Component
public class BeanTester {
@Autowired Properties properties;
public void execute() {
String attr = properties.getProperty("ds.type");
}
}
Upvotes: 58
Reputation: 309
Another way is using a ResourceBundle. Basically you get the bundle using its name without the '.properties'
private static final ResourceBundle resource = ResourceBundle.getBundle("config");
And you recover any value using this:
private final String prop = resource.getString("propName");
Upvotes: 7
Reputation: 941
I'll recommend reading this link https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html from SpringBoot docs about injecting external configs. They didn't only talk about retrieving from a properties file but also YAML and even JSON files. I found it helpful. I hope you do too.
Upvotes: 0
Reputation: 2745
If you need to manually read a properties file without using @Value.
Thanks for the well written page by Lokesh Gupta : Blog
package utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.io.File;
public class Utils {
private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class.getName());
public static Properties fetchProperties(){
Properties properties = new Properties();
try {
File file = ResourceUtils.getFile("classpath:application.properties");
InputStream in = new FileInputStream(file);
properties.load(in);
} catch (IOException e) {
LOGGER.error(e.getMessage());
}
return properties;
}
}
Upvotes: 15
Reputation: 4274
[project structure]: https://i.sstatic.net/RAGX3.jpg
-------------------------------
package beans;
import java.util.Properties;
import java.util.Set;
public class PropertiesBeans {
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
public void getProperty(){
Set keys = properties.keySet();
for (Object key : keys) {
System.out.println(key+" : "+properties.getProperty(key.toString()));
}
}
}
----------------------------
package beans;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext ap = new ClassPathXmlApplicationContext("resource/spring.xml");
PropertiesBeans p = (PropertiesBeans)ap.getBean("p");
p.getProperty();
}
}
----------------------------
- driver.properties
Driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/test
username = root
password = root
----------------------------
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<bean id="p" class="beans.PropertiesBeans">
<property name="properties">
<util:properties location="classpath:resource/driver.properties"/>
</property>
</bean>
</beans>
Upvotes: 0
Reputation: 3527
Here is an additional answer that was also great help for me to understand how it worked : http://www.javacodegeeks.com/2013/07/spring-bean-and-propertyplaceholderconfigurer.html
any BeanFactoryPostProcessor beans have to be declared with a static, modifier
@Configuration
@PropertySource("classpath:root/test.props")
public class SampleConfig {
@Value("${test.prop}")
private String attr;
@Bean
public SampleService sampleService() {
return new SampleService(attr);
}
@Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Upvotes: 28
Reputation: 1493
In configuration class
@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}
Upvotes: 50
Reputation: 2994
You need to put a PropertyPlaceholderConfigurer bean in your application context and set its location property.
See details here : http://www.zparacha.com/how-to-read-properties-file-in-spring/
You might have to modify your property file a bit for this thing to work.
Hope it helps.
Upvotes: 6