首页

通过spring的AbstractRoutingDataSource配置多数据源集成到统一dataSource进行调用

标签:多数据源,路由,AbstractRoutingDataSource,spring,aop,切面,config     发布时间:2016-10-27   

一、用例场景

对于设计复杂业务系统,往往需要接入不同渠道的数据源作为基础数据源datasource,如何在项目中很好的简便扩展数据源模块配置呢?通过spring的AbstractRoutingDataSource继承实现自定义多数据数据源的规范类如CustomerRoutingDataSource,然后通过spring的配置多数据源注册对象到CustomerRoutingDataSource来进行统一路由调度。

二、示例内容

1. Spring配置数据源效果如下,配置数据源dataSourceA、dataSourceB

<?xml version="1.0" encoding="UTF-8"?>@b@<beans xmlns="http://www.springframework.org/schema/beans"@b@		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"@b@		xmlns:aop="http://www.springframework.org/schema/aop"@b@		xmlns:tx="http://www.springframework.org/schema/tx"@b@		xmlns:context="http://www.springframework.org/schema/context"@b@		xsi:schemaLocation="  @b@        	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd@b@        	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd@b@        	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd@b@        	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  @b@	@b@	<context:property-placeholder location="classpath:db.properties "/>@b@	@b@	<!-- DataSource1 proxool Configure -->@b@	<bean id="dataSourceA"  class="org.logicalcobwebs.proxool.ProxoolDataSource" >  @b@	    <property name="driver"><value>${jdbc.driver}</value></property>@b@		<property name="driverUrl"><value>${jdbc.url}</value></property>@b@		<property name="user"><value>${jdbc.username}</value></property>@b@		<property name="password"><value>${jdbc.password}</value></property>@b@		<property name="alias"><value>${jdbc.username}</value></property>@b@		<property name="maximumActiveTime" value="3600000"/>	    @b@	    <property name="prototypeCount" value="5"/>@b@	    <property name="maximumConnectionCount" value="150"/>@b@	    <property name="minimumConnectionCount" value="2"/>@b@	    <property name="trace" value="true"/>@b@	    <property name="verbose" value="true"/>@b@	    <property name="statistics" value="30s,15m"/>@b@	    <property name="simultaneousBuildThrottle" value="30"/>@b@	</bean>@b@	@b@	<!-- DataSource2 proxool Configure -->@b@	<bean id="dataSourceB"  class="org.logicalcobwebs.proxool.ProxoolDataSource" >  @b@	    <property name="driver"><value>${jdbc2.driver}</value></property>@b@		<property name="driverUrl"><value>${jdbc2.url}</value></property>@b@		<property name="user"><value>${jdbc2.username}</value></property>@b@		<property name="password"><value>${jdbc2.password}</value></property>@b@		<property name="alias"><value>${jdbc2.username}</value></property>@b@		<property name="maximumActiveTime" value="3600000"/>	    @b@	    <property name="prototypeCount" value="5"/>@b@	    <property name="maximumConnectionCount" value="150"/>@b@	    <property name="minimumConnectionCount" value="2"/>@b@	    <property name="trace" value="true"/>@b@	    <property name="verbose" value="true"/>@b@	    <property name="statistics" value="30s,15m"/>@b@	    <property name="simultaneousBuildThrottle" value="30"/>@b@	</bean>@b@	@b@ @b@	<bean id="dataSource" class="com.xwood.datasource.CustomerRoutingDataSource">@b@		<property name="targetDataSources">@b@			<map key-type="java.lang.String">@b@				<entry key="dataSource" value-ref="dataSourceA" />@b@				<entry key="dataSource2" value-ref="dataSourceB" />@b@			</map>@b@		</property>@b@		<property name="defaultTargetDataSource" ref="dataSourceA" />@b@	</bean>@b@	@b@	<bean class="com.xwood.datasource.RoutingDataSourceAspect"/>@b@	@b@	<!-- Hibernate Configure -->@b@	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">@b@		<property name="dataSource">@b@			<ref local="dataSource"/>@b@		</property>@b@		<property name="hibernateProperties">@b@			<props>@b@				<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>@b@				<prop key="hibernate.dialect">${hibernate.dialect}</prop>@b@				<prop key="hibernate.cache.use_query_cache">true</prop>@b@				<prop key="hibernate.cache.use_second_level_cache">true</prop>@b@				<prop key="hibernate.show_sql">true</prop>@b@				<prop key="hibernate.format_sql">false</prop>@b@				<prop key="hibernate.jdbc.fetch_size">50</prop>@b@				<prop key="hibernate.jdbc.batch_size">30</prop>@b@				<prop key="hibernate.search.autoregister_listeners">false</prop>@b@				<prop key="hibernate.query.factory_class">org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory</prop>@b@			</props>@b@		</property>		@b@		<property name="packagesToScan">@b@            <list> @b@            	<value>com.xwood.root.model</value> @b@            </list>@b@        </property>@b@	</bean>	@b@	@b@	 @b@	<aop:aspectj-autoproxy />@b@	@b@</beans>

2. 自定义用户数据源路由类CustomerRoutingDataSource

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;@b@@b@public class CustomerRoutingDataSource extends AbstractRoutingDataSource {@b@@b@	  protected Object determineCurrentLookupKey()@b@	  {@b@	    String dsType = CustomerDataSourceContextHolder.getCustomerType();@b@	    return dsType;@b@	  }@b@@b@}

CustomerDataSourceContextHolder解析原子类

public class CustomerDataSourceContextHolder {@b@	  @b@	  public static final String DATA_SOURCE_A = "dataSource";  @b@	  @b@	  public static final String DATA_SOURCE_B = "dataSource2";  @b@	  @b@	  private static final ThreadLocalcontextHolder = new ThreadLocal(); @b@	  @b@	  public static void setCustomerType(String customerType) {  @b@	           contextHolder.set(customerType);  @b@	  }@b@ @b@	  public static String getCustomerType() {  @b@	     return contextHolder.get();  @b@	  } @b@	  @b@	  public static void clearCustomerType() {  @b@	    contextHolder.remove();  @b@	  }  @b@@b@}

3. 初始化解析RoutingDataSourceAspect及RoutingDataSource辅助类

import org.aspectj.lang.annotation.Before;@b@import org.springframework.core.Ordered;@b@ @b@public class RoutingDataSourceAspect implements Ordered {@b@ @b@	  public int getOrder()@b@	  {@b@	    return 199;@b@	  }@b@@b@	  @Before("execution(@org.xwood.datasource.RoutingDataSource * * (..))&& @annotation(routingDataSource)")@b@	  public void route(RoutingDataSource routingDataSource) {@b@	    String key = routingDataSource.key();@b@	    CustomerDataSourceContextHolder.setCustomerType(key);@b@	  }@b@@b@}

RoutingDataSource自定义annotation

import java.lang.annotation.Documented;@b@import java.lang.annotation.Retention;@b@import java.lang.annotation.RetentionPolicy;@b@import java.lang.annotation.Target;@b@@b@@Retention(RetentionPolicy.RUNTIME)@b@@Target({java.lang.annotation.ElementType.METHOD})@b@@Documented@b@public @interface RoutingDataSource@b@{@b@  public abstract String key();@b@}
<<热门下载>>