概述
将应用系统的配置信息存放在配置文件中并非总是最合适的,如果应用以集群的方式部署,或者希望在运行期动态调整引用的某些配置,这时,将配置信息放到数据库中不但方便集中管理,而且可以通过应用系统的管理界面动态维护,有效增强应用系统的可维护性。
早期版本,如果想在配置文件中引用另外一个Bean的属性值是比较麻烦的,Spring3.0则提供了优雅的解决方案. 在Spring3.0中,可以通过类似 #{beanName.beanPro}的方式方便的引用另外一个Bean的值。
实例
代码已托管到Github—> https://github.com/yangshangwei/SpringMaster
假设数据库中有张TEMP_SYS_CONFIG表,数据如下
基于XML方式的引用
beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 扫描@Autowired --> <context:component-scan base-package="com.xgj.ioc.refOtherBeanProByXml"/> <!-- 定义Bean,通过initFromDB初始化方法从数据库中加载数据 --> <bean id="sysConfig" class="com.xgj.ioc.refOtherBeanProByXml.SysConfig" init-method="initFromDB"/> <!-- 引用sysConfig Bean的属性值 --> <bean id="applicationManager" class="com.xgj.ioc.refOtherBeanProByXml.ApplicationManager" p:sessionTimeout="#{sysConfig.sessionTimeout}" p:maxTabPageNum="#{sysConfig.maxTabPageNum}"/> <!-- 使用context命名空间 引入外部属性文件 --> <context:property-placeholder location="classpath:spring/jdbc.properties" /> <!-- 通过属性名引用属性值 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"/> <!-- 配置Jdbc模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" /> </beans>
SysConfig.java
package com.xgj.ioc.refOtherBeanProByXml; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowCallbackHandler; public class SysConfig { public int sessionTimeout; public int maxTabPageNum; private JdbcTemplate jdbcTemplate; @Autowired public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** * * * @Title: initFromDB * * @Description: 从数据库中初始化sessionTimeout和maxTabPageNum属性 * * * @return: void */ public void initFromDB() { System.out.println("initFrom DB"); final List<String> paramList = new ArrayList<String>(); String sql = " select value from TEMP_SYS_CONFIG a where a.code in ('sessionTimeout' ,'maxTabPageNum') "; jdbcTemplate.query(sql, new RowCallbackHandler() { @Override public void processRow(ResultSet rs) throws SQLException { paramList.add(rs.getString("value")); } }); sessionTimeout = Integer.parseInt(paramList.get(0)); maxTabPageNum = Integer.parseInt(paramList.get(1)); } }
ApplicationManager.java
package com.xgj.ioc.refOtherBeanProByXml; public class ApplicationManager { private int sessionTimeout; private int maxTabPageNum; public int getSessionTimeout() { System.out.println("sessionTimeout:" + sessionTimeout); return sessionTimeout; } public void setSessionTimeout(int sessionTimeout) { this.sessionTimeout = sessionTimeout; } public int getMaxTabPageNum() { System.out.println("maxTabPageNum:" + maxTabPageNum); return maxTabPageNum; } public void setMaxTabPageNum(int maxTabPageNum) { this.maxTabPageNum = maxTabPageNum; } }
测试类
package com.xgj.ioc.refOtherBeanProByXml; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanPropReferenceTest { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath:com/xgj/ioc/refOtherBeanProByXml/beans.xml"); ApplicationManager applicationManager = ctx.getBean( "applicationManager", ApplicationManager.class); applicationManager.getSessionTimeout(); applicationManager.getMaxTabPageNum(); } }
运行结果:
基于注解的引用
在基于注解和基于JAVA类配置的Bean中,可以通过@Value(“#{beanName.beanPro}”)的注解形式引用Bean的属性值
通过在配置文件中配置context:component-scan ,扫描标注了注解的POJO,实例化并缓存。
配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 --> <context:component-scan base-package="com.xgj.ioc.refOtherBeanPro"/> <!-- 使用context命名空间 引入外部属性文件 --> <context:property-placeholder location="classpath:spring/jdbc.properties" /> <!-- 通过属性名引用属性值 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"/> <!-- 配置Jdbc模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" /> </beans>
SysConfig.java
package com.xgj.ioc.refOtherBeanPro; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.stereotype.Component; @Component public class SysConfig { public int sessionTimeout; public int maxTabPageNum; private JdbcTemplate jdbcTemplate; @Autowired public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** * * * @Title: initFromDB * * @Description: 从数据库中初始化sessionTimeout和maxTabPageNum属性 * * * @return: void */ @PostConstruct public void initFromDB() { System.out.println("initFrom DB"); final List<String> paramList = new ArrayList<String>(); String sql = " select value from TEMP_SYS_CONFIG a where a.code in ('sessionTimeout' ,'maxTabPageNum') "; jdbcTemplate.query(sql, new RowCallbackHandler() { @Override public void processRow(ResultSet rs) throws SQLException { paramList.add(rs.getString("value")); } }); sessionTimeout = Integer.parseInt(paramList.get(0)); maxTabPageNum = Integer.parseInt(paramList.get(1)); } }
ApplicationManager.java
package com.xgj.ioc.refOtherBeanPro; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class ApplicationManager { private int sessionTimeout; private int maxTabPageNum; public int getSessionTimeout() { System.out.println("sessionTimeout:" + sessionTimeout); return sessionTimeout; } @Value("#{sysConfig.sessionTimeout}") public void setSessionTimeout(int sessionTimeout) { this.sessionTimeout = sessionTimeout; } public int getMaxTabPageNum() { System.out.println("maxTabPageNum:" + maxTabPageNum); return maxTabPageNum; } @Value("#{sysConfig.maxTabPageNum}") public void setMaxTabPageNum(int maxTabPageNum) { this.maxTabPageNum = maxTabPageNum; } }
测试类
package com.xgj.ioc.refOtherBeanPro; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanPropReferenceTest { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath:com/xgj/ioc/refOtherBeanPro/beans.xml"); ApplicationManager applicationManager = ctx.getBean( "applicationManager", ApplicationManager.class); applicationManager.getSessionTimeout(); applicationManager.getMaxTabPageNum(); } }
运行结果: