Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure a Spring beans with properties that are stored in a database table

Tags:

In my project we'd like to externalize the properties of our Spring managed beans, that is very easy to do with standard Java .properties files, however we want to be able to read those properties from a DB table that behaves like a Map (key is the property name, value is the value assigned to that property).

I found this post that suggest the usage of Commons Configuration but I don't know if there's a better way to do the same with Spring 3.x. Maybe implementing my own PropertyResource or something.

Any clues?

like image 743
Eliseo Soto Avatar asked Jan 04 '11 22:01

Eliseo Soto


People also ask

Which tag is used to configure the property of the bean?

The jsp:setProperty action tag sets a property value or values in a bean using the setter method.

How are beans configured in Spring?

There are several ways to configure beans in a Spring container. Firstly, we can declare them using XML configuration. We can also declare beans using the @Bean annotation in a configuration class. Finally, we can mark the class with one of the annotations from the org.


2 Answers

I'd use a FactoryBean of type <Properties> that I'd implement using JdbcTemplate. You can then use the generated Properties object with the <context:property-placeholder> mechanism.

Sample code:

public class JdbcPropertiesFactoryBean
    extends AbstractFactoryBean<Properties>{

    @Required
    public void setJdbcTemplate(final JdbcTemplate jdbcTemplate){
        this.jdbcTemplate = jdbcTemplate;
    }
    private JdbcTemplate jdbcTemplate;

    @Required
    public void setTableName(final String tableName){
        this.tableName = tableName;
    }
    private String tableName;

    @Required
    public void setKeyColumn(final String keyColumn){
        this.keyColumn = keyColumn;
    }
    private String keyColumn;

    @Required
    public void setValueColumn(final String valueColumn){
        this.valueColumn = valueColumn;
    }
    private String valueColumn;

    @Override
    public Class<?> getObjectType(){
        return Properties.class;
    }

    @Override
    protected Properties createInstance() throws Exception{
        final Properties props = new Properties();
        jdbcTemplate.query("Select " + keyColumn + ", " + valueColumn
            + " from " + tableName, new RowCallbackHandler(){

            @Override
            public void processRow(final ResultSet rs) throws SQLException{
                props.put(rs.getString(1), rs.getString(2));
            }

        });
        return props;
    }
}

XML Configuration:

<bean id="props" class="foo.bar.JdbcPropertiesFactoryBean">
    <property name="jdbcTemplate">
        <bean class="org.springframework.jdbc.core.JdbcTemplate">
            <!-- reference to a defined data source -->
            <constructor-arg ref="dataSource" />
        </bean>
    </property>
    <property name="tableName" value="TBL_PROPERTIES" />
    <property name="keyColumn" value="COL_KEY" />
    <property name="valueColumn" value="COL_VAL" />
</bean>

<context:property-placeholder properties-ref="props" />
like image 144
Sean Patrick Floyd Avatar answered Oct 15 '22 00:10

Sean Patrick Floyd


In addition to Sean's suggestion, you can extend PropertyPlaceholderConfigurer. Look at the two current implementations - PreferencesX and ServletContextX, and roll out your own, jdbc-based.

like image 39
Bozho Avatar answered Oct 14 '22 23:10

Bozho