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);