package cn.org.rapid_framework.spring.beans.factory.config; import java.util.Properties; import javax.sql.DataSource; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.util.Assert; /** * 通过数据库解析spring placeholder的值,配置示例 * * * <pre> * <bean id="propertyConfigurer" class="cn.org.rapid_framework.spring.beans.factory.config.JdbcPlaceholderConfigurer"> * <property name="dataSource" ref="dataSource"/> * <property name="sql" value="select config_value,[default_value] from t_app_config where config_key = ?"/> * </bean> * </pre> * [default_value]列可选 * ?号为传递的placeholder的值 * @author badqiu * */ public class JdbcPlaceholderConfigurer extends PropertyPlaceholderConfigurer implements InitializingBean{ private DataSource dataSource; private String sql; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void setSql(String sql) { this.sql = sql; } public void afterPropertiesSet() throws Exception { Assert.notNull(dataSource,"'dataSource' property must be not null"); Assert.hasText(sql,"'sql' property must be not empty"); logger.info("spring resolve placeholder sql:"+sql); } protected String resolvePlaceholder(String placeholder, Properties props,int systemPropertiesMode) { String value = super.resolvePlaceholder(placeholder, props, systemPropertiesMode); if(value == null) { try { value = resolveJdbcPlaceholder(placeholder); }catch(RuntimeException e) { throw new BeanDefinitionStoreException("resolve placeholder by jdbc sql error,placeholder="+placeholder,e); } } return value; } private String resolveJdbcPlaceholder(String placeholder) { SqlRowSet rs = new JdbcTemplate(dataSource).queryForRowSet(sql,new Object[]{placeholder}); int columnCount = rs.getMetaData().getColumnCount(); Assert.isTrue(columnCount == 1 || columnCount == 2,"error resultSet columnCount,sql example: select config_value,[default_value] from app_config where config_key=?,[default_value] is option"); if(!rs.next()) return null; switch(columnCount) { case 1: return rs.getString(1); case 2: String value = rs.getString(1); String defaultValue = rs.getString(2); if(value == null) { value = defaultValue; } return value; default: throw new IllegalArgumentException("error columnCount:"+columnCount+", sql:"+sql); } } }