spring系列之-多个数据源配置

1、spring-context.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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- 数据同步的数据源配置 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
		<property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" 
		value="jdbc:mysql://IP:3306/amb_car_accessory?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true" 
		/> <property name="user" value="" /> <property name="password" value="" 
		/> <property name="minPoolSize" value="1" /> <property name="maxPoolSize" 
		value="30" /> <property name="maxIdleTime" value="1800" /> <property name="acquireIncrement" 
		value="2" /> <property name="maxStatements" value="100" /> <property name="initialPoolSize" 
		value="2" /> <property name="idleConnectionTestPeriod" value="1800" /> <property 
		name="acquireRetryAttempts" value="30" /> <property name="acquireRetryDelay" 
		value="100" /> <property name="breakAfterAcquireFailure" value="false" /> 
		<property name="testConnectionOnCheckout" value="true" /> </bean> -->
	<!-- 多数据源配置使用开始 -->
	<bean id="dataSourceDefault" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url"
			value="jdbc:mysql://IP:8066/amb_admin?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true" />
		<property name="username" value="" />
		<property name="password" value="" />
		<property name="maxActive" value="20" /><!-- 连接池最大使用连接数 -->
		<property name="initialSize" value="1" /><!-- 初始化连接大小 -->
		<property name="maxWait" value="60000" /><!-- 获取连接最大等待时间 -->
		<property name="minIdle" value="3" /><!-- 连接池最小空闲 -->
		<property name="removeAbandoned" value="true" /><!-- 自动清除无用连接 -->
		<property name="removeAbandonedTimeout" value="1800" /><!-- 清除无用连接的等待时间 -->
		<property name="connectionProperties" value="clientEncoding=UTF-8" /><!-- 
			连接属性 -->
	</bean>

	<bean id="dataSourceOrder" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url"
			value="jdbc:mysql://IP:8066/hx_maintain?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true" />
		<property name="username" value="" />
		<property name="password" value="" />
		<property name="maxActive" value="20" /><!-- 连接池最大使用连接数 -->
		<property name="initialSize" value="1" /><!-- 初始化连接大小 -->
		<property name="maxWait" value="60000" /><!-- 获取连接最大等待时间 -->
		<property name="minIdle" value="3" /><!-- 连接池最小空闲 -->
		<property name="removeAbandoned" value="true" /><!-- 自动清除无用连接 -->
		<property name="removeAbandonedTimeout" value="1800" /><!-- 清除无用连接的等待时间 -->
		<property name="connectionProperties" value="clientEncoding=UTF-8" /><!-- 
			连接属性 -->
	</bean>
	<!-- <bean id="multipleDataSource" class="com.hxqc.accessory.datasource.MultipleDataSource"> 
		<property name="defaultTargetDataSource" ref="dataSource" /> <property name="targetDataSources"> 
		<map> <entry key="dataSource" value-ref="dataSource" /> <entry key="dataSourceOrder" 
		value-ref="dataSourceOrder" /> </map> </property> </bean> -->
	<bean id="dataSource"
		class="com.hxqc.accessory.datasource.ThreadLocalRountingDataSource">
		<property name="defaultTargetDataSource" ref="dataSourceDefault" />
		<property name="targetDataSources">
			<map key-type="com.hxqc.accessory.datasource.DataSources">
				<entry key="DATASOURCE_DEFAULT" value-ref="dataSourceDefault" />
				<entry key="DATASOURCE_ORDER" value-ref="dataSourceOrder" />
				<!-- 这里还可以加多个dataSource -->
			</map>
		</property>
	</bean>
	<!-- 多数据源配置使用结束 -->
	<!-- myBatis文件 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation" value="classpath:configuration.xml" />
		<property name="mapperLocations"
			value="classpath:com/hxqc/accessory/mapper/*Mapper.xml" />
	</bean>

	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage"
			value="com.hxqc.accessory.mapper,com.hxqc.accessory.app.mapper,com.hxqc.accessory.web.mapper" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
	</bean>

	<!-- 配置事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<tx:annotation-driven transaction-manager="transactionManager" />

	<aop:aspectj-autoproxy />

	<context:component-scan
		base-package="com.hxqc.accessory.service,com.hxqc.accessory.*.service,com.hxqc.accessory.interceptor"></context:component-scan>


	<context:property-placeholder location="classpath:redis.properties" />

	<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxIdle" value="${redis.maxIdle}" />
		<property name="maxTotal" value="${redis.maxTotal}" />
		<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
		<property name="testOnBorrow" value="true"></property>
		<property name="testOnReturn" value="true"></property>
		<property name="testWhileIdle" value="${redis.testWhileIdle}"></property>
	</bean>

	<bean id="jedisConnectionFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		p:database="${redis.default.db}" p:host-name="${redis.host}" p:port="${redis.port}"
		p:usePool="true" p:password="${redis.pass}" p:pool-config-ref="poolConfig" />

	<bean id="shopConnectionFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		p:database="${shop.default.db}" p:host-name="${shop.host}" p:port="${shop.port}"
		p:usePool="true" p:password="${shop.pass}" p:pool-config-ref="poolConfig" />

	<bean id="brandConnectionFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		p:database="${brand.default.db}" p:host-name="${brand.host}" p:port="${brand.port}"
		p:usePool="true" p:password="${brand.pass}" p:pool-config-ref="poolConfig" />


	<bean id="brandTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
		<property name="connectionFactory" ref="brandConnectionFactory" />
	</bean>

	<bean id="stringTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
		<property name="connectionFactory" ref="jedisConnectionFactory" />
	</bean>

	<bean id="shopStringTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
		<property name="connectionFactory" ref="shopConnectionFactory" />
	</bean>
	<!-- <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> 
		<property name="connectionFactory" ref="jedisConnectionFactory" /> </bean> -->

	<bean id="connectionFactory"
		class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
		<constructor-arg value="IP" />
		<property name="port" value="5672" />
		<property name="username" value="hx" />
		<property name="password" value="hx" />
		<property name="channelCacheSize" value="25" />
	</bean>
	<bean id="amqpAdmin" class="org.springframework.amqp.rabbit.core.RabbitAdmin">
		<constructor-arg ref="connectionFactory" />
	</bean>
	<bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate">
		<constructor-arg ref="connectionFactory"></constructor-arg>
	</bean>

	<bean id="schedulerFactoryBean"
		class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="dataSource">
			<ref bean="dataSourceDefault" />
		</property>
		<property name="jobFactory">
			<bean class="com.hxqc.accessory.quartz.SpringBeanJobFactory" />
		</property>
		<property name="quartzProperties">
			<props>
				<prop key="org.quartz.scheduler.instanceName">quartzScheduler</prop>
				<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
				<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
				<prop key="org.quartz.threadPool.threadCount">3</prop>
				<prop key="org.quartz.threadPool.threadPriority">5</prop>
				<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
				<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
				<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate </prop>
				<prop key="org.quartz.jobStore.selectWithLockSQL">SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?
				</prop>
				<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
				<prop key="org.quartz.jobStore.isClustered">true</prop>
				<prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>
			</props>
		</property>
		<property name="applicationContextSchedulerContextKey" value="applicationContextKey" />
		<property name="autoStartup" value="true" />
	</bean>
	
	<task:annotation-driven/>  
	<!-- 上线后开启,定时优化索引
	<bean id="systemScheduleJob" class="com.hxqc.accessory.quartz.SystemScheduleJob"></bean>
	 -->
</beans>

2、JAVA文件DataSources.class

 

 

package com.hxqc.accessory.datasource;

public enum DataSources {
	DATASOURCE_DEFAULT, DATASOURCE_ORDER
}

DataSourceAnnotation.class

 

 

package com.hxqc.accessory.interceptor;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSourceAnnotation {
	com.hxqc.accessory.datasource.DataSources value();
}

DataSourceInterceptor

package com.hxqc.accessory.interceptor;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.hxqc.accessory.datasource.DataSourceTypeManager;

@Aspect
// for aop
@Component
// for auto scan
@Order(0)
// execute before @Transactional
public class DataSourceInterceptor {

	private static final Logger LOG = org.slf4j.LoggerFactory
			.getLogger(DataSourceInterceptor.class);

	// @Before("execution(public * com.hxqc.accessory.service.AmbOrderService.*(..))")
	@Around("execution(public * com.hxqc.accessory.service.*.*(..)) && @annotation(com.hxqc.accessory.interceptor.DataSourceAnnotation)")
	// @Around("execution(public * *Order*(..))")
	public Object beforeOrder(ProceedingJoinPoint pjp) throws Throwable {
		DataSourceAnnotation dataSourceAnnotation = getAnnotation(pjp);
		LOG.info("切换后数据源:{}", dataSourceAnnotation.value());
		DataSourceTypeManager.set(dataSourceAnnotation.value());
		try {
			Object value = pjp.proceed();
			return value;
		} finally {
			DataSourceTypeManager.reset();
		}
	}

	/**
	 * 获得注释内容
	 * 
	 * @param joinPoint
	 * @return
	 */
	private DataSourceAnnotation getAnnotation(JoinPoint joinPoint) {
		Signature signature = joinPoint.getSignature();
		MethodSignature methodSignature = (MethodSignature) signature;
		Method method = methodSignature.getMethod();
		if (method != null) {
			return method.getAnnotation(DataSourceAnnotation.class);
		}
		return null;
	}

}

DataSourceTypeManager.class

package com.hxqc.accessory.datasource;

public class DataSourceTypeManager {
	private static final ThreadLocal<DataSources> dataSourceTypes = new ThreadLocal<DataSources>() {
		@Override
		protected DataSources initialValue() {
			return DataSources.DATASOURCE_DEFAULT;
		}
	};

	public static DataSources get() {
		return dataSourceTypes.get();
	}

	public static void set(DataSources dataSourceType) {
		dataSourceTypes.set(dataSourceType);
	}

	public static void reset() {
		dataSourceTypes.set(DataSources.DATASOURCE_DEFAULT);
	}
}

ThreadLocalRountingDataSource.class

 

package com.hxqc.accessory.datasource;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class ThreadLocalRountingDataSource extends AbstractRoutingDataSource {
	@Override
	protected Object determineCurrentLookupKey() {
		return DataSourceTypeManager.get();
	}
}

 

切换数据源:DataSourceTypeManager.set(DataSources.DATASOURCE_ORDER);

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值