Reading valued from properties file at Runtime - spring

I want to get specific value based on request from the property file.how to do that?
I have following spring configuration.i want to set the value for Exprops as per the request and get corresponding values from the properties file
<bean id="Prop" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:ErrorMessage.properties</value>
</property>
</bean>
<bean id="PropertiesBean" class="com.util.PropertiesUtil">
<property name="Exprops" value="${EXampleExceptiion}"></property>
</bean>

Use the PropertiesFactoryBean to inject the Properties in a Bean.
<bean id="myPropertiesBean"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:ErrorMessage.properties"/>
</bean>
This provides a Properties Object/Bean which can be injected under the name myPropertiesBean in any Bean (<property name="x" ref="myPropertiesBean"/>).
In addition Spring provides the util namespace (since Spring 2.5):
There you can write the PropertyFactoryBean definition a bit shorter:
<util:properties id="myPropertiesBean"
location="classpath:ErrorMessage.properties"/>
#see Spring Reference Chapter C.2.2.3.

All use the following for doing this programmatically
XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml"));
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
cfg.postProcessBeanFactory(factory);

<util:properties id="" location="location of prop file" />
this return java.util.Properties object

Related

How to get key value from properties file at runtime using spring

I want to get the changed key value from properties file at runtime.
test.properties file:
name = Hi
I have made Thread sleep with 5 sec and changed the key value as "Hello" but it is not getting changed.
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:test.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:test</value>
</list>
</property>
<property name="cacheSeconds" value="1" />
</bean>
<bean id="tempBean" name="tempBean1" class="org.sri.spring.temp.Temp"
lazy-init="false" scope="prototype">
<constructor-arg type="String" value="${name}" />
</bean>
The ${name} placeholder inside the XML configuration is resolved using the PropertySourcesPlaceholderConfigurer which, as you may notice, has nothing in common with your reloadable messageSource.
It wouldn't work either way because Spring instantiates the tempBean only once: on application startup, by passing the value of ${name} to the constructor. The bean itself is not aware of where the value came from (and in particular, it doesn't care if the properties file gets edited).
If you really think it's a good idea to do it†, you can inject the entire messageSource into your tempBean, and get the current value in each call, e.g.:
public class Temp {
#Autowired // or wired in XML, constructor, etc.
private MessageSource messages;
public String sayHello() {
return messages.getMessage("name", null, Locale.getDefault());
}
}
† injecting a configuration-related object makes testing more difficult and is arguably bad design (mixing concerns). Have a look at the Spring Cloud Config project as it's likely that this is how the future is going to look like.
I do not think that Spring will update already existing beans when the properties change.
Try to create a new bean (prototype scope)

context:property-holder Vs. PropertyPlaceholderConfigurer

How do I make use of #Value in the following 2 cases?
case 1: I have a PropertyPlaceholderConfigurer bean defined as follows
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:#{ systemProperties['user.home']}/myconf/settings.properties</value>
</property>
</bean>
Case 2: I did not define the bean, but i have declared property-place holder in the context as follows
<context:property-placeholder
location="file:#{ systemProperties['user.home']}/myconf/settings.properties" />
In both cases you would use like
#Value(value="${key.in.file}")
private String myVar;

spring bean initializing instances differently via property wiring

I have the following properties in a property file:
context1.property1=value1
context1.property2=value2
context1.property3=value3
context2.property1=value4
context2.property2=value5
context2.property3=value6
I have a bean with the following structure:
class Bean {
private property1;
private property2;
private property3;
}
Is there any way better to initialize 2 instances of Bean without writing something like:
<bean id="bean1" class="com.test.Bean">
<property name="property1" value="${context1.value1}" />
<property name="property2" value="${context1.value2}" />
<property name="property3" value="${context1.value3}" />
</bean>
<bean id="bean2" class="com.test.Bean">
<property name="property1" value="${context2.value1}" />
<property name="property2" value="${context2.value2}" />
<property name="property3" value="${context2.value3}" />
</bean>
Thanks!
Have a look at PropertyOverrideConfigurer:
Property resource configurer that overrides bean property values in an application context definition. It pushes values from a properties file into bean definitions.
Configuration lines are expected to be of the following form:
beanName.property=value
Example properties file:
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql:mydb
See also
Using PropertyOverrideConfigurer with Annotated Classes in Spring 3

Is there a better way to Configure Bean?

Can the following Spring DI xml be improved? Below the xml is the programmatic approach of configuring the target bean.
<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
<bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig"
factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" />
<bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jacksonSerializationConfig" />
<property name="targetMethod" value="setSerializationInclusion" />
<property name="arguments">
<list>
<value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_NULL</value>
</list>
</property>
</bean>
ObjectMapper mapper = new
ObjectMapper();
mapper.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
XML is a really bad way of doing this. Yes, you can do this, but it's much easier to write a FactoryBean which configures your ObjectMapper:
public class MyObjectMapperFactoryBean extends AbstractFactoryBean<ObjectMapper> {
public Class<ObjectMapper> getObjectType() {
return ObjectMapper.class;
}
public ObjectMapper createInstance() {
// create and return ObjectMapper
}
}
and then in your XML:
<bean id="jacksonObjectMapper" class="x.y.MyObjectMapperFactoryBean" />
Still not totally ideal, but a little cleaner:
<bean id="objectMapperBuilder1" class="org.codehaus.jackson.map.ObjectMapper"/>
<bean id="objectMapperBuilder2" factory-bean="objectMapperBuilder1" factory-method="setSerializationInclusion">
<constructor-arg value="NON_NULL"/>
</bean>
<bean id="jsonWriter" factory-bean="objectMapperBuilder2" factory-method="writerWithDefaultPrettyPrinter" />
<!-- etc, etc -->
One downside is that you'll have unnecessary bean instances in memory. (I'm using this method, and I'll live with it until Spring decides to handle these). There are many threads here and on the Spring forums asking for support with fluent setters like the builder pattern used by Jackson, but until then you have to choose the lesser evil for you.
I agree with #skaffman's general approach of using a FactoryBean in place of the unavoidably convoluted Spring XML bean configuration to configure a Jackson ObjectMapper. Spring 3.2+ now provides such a FactoryBean out of the box. See JacksonObjectMapperFactoryBean / Jackson2ObjectMapperFactoryBean. Here's an example of the Spring XML to configure the ObjectMapper via the Spring FactoryBean -
<bean id="jacksonObjectMapper" factory-bean="&jacksonObjectMapperFactoryBean" factory-method="getObject"/>
<bean id="jacksonObjectMapperFactoryBean" class="org.springframework.http.converter.json.JacksonObjectMapperFactoryBean">
<property name="featuresToDisable">
<array>
<util:constant static-field="org.codehaus.jackson.map.SerializationConfig$Feature.WRITE_NULL_PROPERTIES"/>
</array>
</property>
</bean>
(Note the need to use &amp in the 'factory-bean' attribute to instruct Spring to use the factory method on the FactoryBean itself, rather than the bean it creates).

Spring - Retrieve value from properties file

I have the following configuration in my applicationContext.xml:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:app.properties</value>
</list>
</property>
</bean>
Now, in my java class, how can I read the values from the file app.properties?
With Spring 3.0 you can use the #Value annotation.
#Component
class MyComponent {
#Value("${valueKey}")
private String valueFromPropertyFile;
}
Actually PropertyPlaceholderConfigurer is useful to inject values to spring context using properties.
Example XML context definition:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>${driver}</value></property>
<property name="url"><value>jdbc:${dbname}</value></property>
</bean>`
Example properties file:
driver=com.mysql.jdbc.Driver
dbname=mysql:mydb
Or you can create bean like
<bean name="myBean" value="${some.property.key}" />
and then inject this bean into your class

Resources