上一篇介绍了基于annotation的分布式配置管理,但该种方式对代码的侵入性太大,我们已有很多项目需要使用该配置平台,所以不能有太多的代码侵入性,这篇来介绍下基于xml的分布式配置管理,以mysql举例,我们项目中连接mysql是用的spring-data-jpa。
同基于annotation的分布式配置管理一样,我们需要首先在pom中引入disconf的依赖,准备好disconf.properties文件放入到项目中resources文件夹下,修改applicationContext.xml加入相应的配置。
- 数据准备
DROP DATABASE IF EXISTS `disconf_demo`; CREATE DATABASE `disconf_demo`; USE `disconf_demo`;
-- ---------------------------- -- Table structure for `activity` -- ---------------------------- DROP TABLE IF EXISTS `activity`; CREATE TABLE `activity` ( `id` int(11) NOT NULL AUTO_INCREMENT, `start` date DEFAULT NULL, `end` date DEFAULT NULL, `launcher` varchar(256) NOT NULL, `name` varchar(256) DEFAULT NULL, `prize_money` int(11) DEFAULT NULL, `type` varchar(256) NOT NULL, `valid` bit(1) DEFAULT NULL, `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into activity values(1,'2015-01-01','2016-01-01','sms','i am test activity',10,1,'2015-01-01 12:12:12'); 同样我们再新建一个disconf_demo2这个数据库,表一模一样,插入一条数据 insert into activity values(1,'2015-01-01','2016-01-01','sms','change the name',10,1,'2015-01-01 12:12:12');
- xml分布式配置管理
为了使用基于xml的分布式配置管理,我们需要在applicationContext.xml中加入如下bean: <bean id="autoReloadBean" class="com.baidu.disconf.client.addons.properties.ReloadablePropertiesFactoryBean"> <property name="locations"> <list> <value>mysql.properties</value> </list> </property> </bean> <bean id="autoReloadConfig" class="com.baidu.disconf.client.addons.properties.ReloadingPropertyPlaceholderConfigurer"> <property name="ignoreResourceNotFound" value="true"/> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="propertiesArray"> <list> <ref bean="autoReloadBean"/> </list> </property> </bean>
- 实例
上传mysql.properties文件到disconf-web中,内容如下: # mysql mysql.driverClassName=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://localhost/disconf_demo?characterEncoding=utf8 mysql.username=root mysql.password=root controller代码如下: @Controller @RequestMapping("/query") public class QueryController {
@Autowired private MysqlService mysqlService;
@RequestMapping(value = "mysql",method = RequestMethod.GET) @ResponseBody public String getMysql() { return this.mysqlService.getActivityName(); } }
service代码如下: @Service public class MysqlService {
@Autowired private ActivityRepository activityRepository;
public String getActivityName() { return this.activityRepository.findOne(1).getName(); } } repository代码如下:
public interface ActivityRepository extends PagingAndSortingRepository<Activity,Integer> {
/** * 查询状态和时间段有效的活动 * * @param start * @param end * @return */ List<Activity> findByValidTrueAndStartBeforeAndEndAfter(Date start,Date end);
/** * 查询有效的活动 * * @return */ List<Activity> findByValidTrue(); }
我们重点看下jpa的配置: <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${mysql.driverClassName}" p:url="${mysql.url}" p:username="${mysql.username}" p:password="${mysql.password}" p:maxIdle="5" p:maxActive="40" p:defaultAutoCommit="true" p:timeBetweenEvictionRunsMillis="3600000" p:minEvictableIdleTimeMillis="3600000" />
<bean id="entityManagerFactory" name="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property> <property name="packagesToScan" value="xxx.disconf.demo.domain" /> <property name="jpaProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.max_fetch_depth">3</prop> <prop key="hibernate.jdbc.fetch_size">50</prop> <prop key="hibernate.jdbc.batch_size">10</prop> <prop key="hibernate.show_sql">false</prop> </props> </property> </bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory" />
<jpa:repositories base-package="xxx.disconf.demo.repository" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" />
<tx:annotation-driven transaction-manager="transactionManager" /> 我们可以看到,配置方式和不使用disconf一模一样,做到了无代码侵入性。
- 自动reload
我们在disconf-web上将jdbc:mysql://localhost/disconf_demo?characterEncoding=utf8修改成 jdbc:mysql://localhost/disconf_demo2?characterEncoding=utf8,然后再去调这个接口,理论上应该返回的是 change the name,但实际上还是和之前一样。
这里我们使用的是ReloadingPropertyPlaceholderConfigurer(
PropertyPlaceholderConfigurer只是托管,不会自动reload ),理论上应该会自动reload,但是实际上却没有。我们仔细看jpa的配置,disconf管理的bean是dataSource,所以当配置更新时仅仅更新了dataSource这个bean,并不会对下面的几个bean产生影响。所以自动reload了,但是我们看不到效果。
实际上像这种mysql等连接比较重的资源,用disconf进行托管即可,不需要做到自动reload。
参考:https://github.com/knightliao/disconf/wiki
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|