juneSakura
juneSakura

Reputation: 133

Spring Reload Property - Bean not updated

I have a webservice that fetches property from application.properties file located in server like query[testSql] through spring

public class RuntimeEnvironmentPropertiesConfigurerextends PropertyPlaceholderConfigurer
        implements InitializingBean, RuntimeEnvironmentInterface

Now that query is injected in my Spring bean dao.

<bean id="dao" name="dao" class="com.dao.DaoImpl">
  <property name="ackJdbcTemplate"  ref="ackJdbcTemplate" />  
  <property name="testSql" value="${dao.query.tSql}" />
 </bean>

With help from How can I reload properties file in Spring 4 using annotations? link I am able to reload the property at run time. verified by

@Autowired
public RuntimeEnvironmentInterface propertyLoader;

....

  Set s=propertyLoader.getProperties();
        Iterator itr=s.iterator();
        while(itr.hasNext()){
        String tempKey=String.valueOf(itr.next());
        logger.info(tempKey +"==="+propertyLoader.getProperty(tempKey));

but problem is my dao bean does not take updated testSql query.It runs on old one untill I restart the application.

I found a way like in separate url mapping i wrote a method which does below job:

Dao.setTestSql(propertyLoader.getProperty("com.dao.query.tSql"));

and the person who is updating she have to hit the url after updating the property.

But this I have to do for all the bean and and injected property.That is pretty hectic job.I miss one property and I am doomed. Is there any other way to automatically update the injected bean?I need that my updated properties are reflected without restart .

I tried to understand wuenschenswert code given but was unable to.

Upvotes: 1

Views: 1151

Answers (1)

Roman Puchkovskiy
Roman Puchkovskiy

Reputation: 11835

<property name="testSql" value="${dao.query.tSql}" />

This means that on bean initialization Spring computes the property value using a property called dao.query.tSql. So setTestSql() method will be called when the context is initialized, and that's all. When your properties are reloaded, property loader will not push new property value into your bean.

But, as Alexey suggests, you can pull the property value from your propertyLoader every time you execute that sql query like this:

final String actualQuery = propertyLoader.getProperty("com.dao.query.tSql");
executeQuery(actualQuery);

There is a problem: this may start look ugly when the number of properties grows. But this can be alleviated, if you create some class encapsulating these accesses; that class will provide properties via its methods. Example:

public class DynamicProperties {
    private final RuntimeEnvironmentInterface propertyLoader;

    public DynamicProperties(RuntimeEnvironmentInterface propertyLoader) {
        this.propertyLoader = propertyLoader;
    }

    public String tSql() {
        return propertyLoader.getProperty("dao.query.tSql");
    }

    ... other methods for other properties
}

Then create an instance of this class in your Dao:

private DynamicProperties dynamicProperties = new DynamicProperties(propertyLoader);

And then

executeQuery(dynamicProperties.tSql());

A little bonus: you can make type conversions in that same DynamicProperties class (for example, when your property is int and not String).

Upvotes: 2

Related Questions