*.properties配置:

<!--数据连接配置一-->

jdbc.type=mysql
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3066/qshop?useUnicode=true&amp;characterEncoding=UTF-8&amp;useFastDateParsing=false&amp;allowMultiQueries=true&amp;serverTimezone=GMT%2b8
jdbc.username=xxxxx
jdbc.password=xxxx

<!--数据连接配置二-->

merchant.jdbc.type=mysql
merchant.jdbc.driver=com.mysql.jdbc.Driver
merchant.jdbc.url=jdbc:mysql://localhost:3066/qshop_merchant?useUnicode=true&amp;characterEncoding=UTF-8&amp;useFastDateParsing=false&amp;allowMultiQueries=true&amp;serverTimezone=GMT%2b8
merchant.jdbc.username=xxxx
merchant.jdbc.password=xxxx

spring-application.xml配置:

<!-- 数据源一、数据源配置, 使用 druid 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}"/>

<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>

<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}"/>
<property name="minIdle" value="${jdbc.pool.minIdle}"/>
<property name="maxActive" value="${jdbc.pool.maxActive}"/>

<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000"/>

<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>

<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>

<property name="validationQuery" value="${jdbc.testSql}"/>
<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>

<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->

<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat"/>
</bean>

<!-- 数据源二、商家数据源配置, 使用 druid 数据库连接池 -->
<bean id="merchantdataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${merchant.jdbc.driver}"/>

<!-- 基本属性 url、user、password -->
<property name="url" value="${merchant.jdbc.url}"/>
<property name="username" value="${merchant.jdbc.username}"/>
<property name="password" value="${merchant.jdbc.password}"/>

<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}"/>
<property name="minIdle" value="${jdbc.pool.minIdle}"/>
<property name="maxActive" value="${jdbc.pool.maxActive}"/>

<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000"/>

<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>

<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>

<property name="validationQuery" value="${jdbc.testSql}"/>
<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>

<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->

<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat"/>
</bean>

<!--配置动态数据源-->

<bean id="dynamicDataSource" class="com.yryz.qshop.modules.dynamiclink.DynamicDataSource">

<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- 指定lookupKey和与之对应的数据源 -->
<entry key="dataSource" value-ref="dataSource"></entry>
<entry key="merchantdataSource" value-ref="merchantdataSource"></entry>
</map>
</property>
<!-- 这里可以指定默认的数据源 {最好不要指定,指定后有坑}-->
<!-- <property name="defaultTargetDataSource" ref="dataSource" /> -->
</bean>

<bean id="dataSourceAspect" class="com.yryz.qshop.modules.dynamiclink.aspect.DataSourceAspect"/>
<aop:config>
<aop:aspect ref="dataSourceAspect">
<aop:pointcut id="dataSourcePointcut" expression="execution(* com.yryz.qshop.modules.merchantremote.service.*.*(..))"/>
<aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
</aop:aspect>
</aop:config>

动态数据源类:

DynamicDataSourceHolder.java

package com.yryz.qshop.modules.dynamiclink;

public class DynamicDataSourceHolder {

/**
* 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
*/
private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>();

public static String getDataSource() {
return THREAD_DATA_SOURCE.get();
}

public static void setDataSource(String dataSource) {
THREAD_DATA_SOURCE.set(dataSource);
}

public static void clearDataSource() {
THREAD_DATA_SOURCE.remove();
}

}

DynamicDataSource.java

package com.yryz.qshop.modules.dynamiclink;

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

public class DynamicDataSource extends AbstractRoutingDataSource{

@Override
protected Object determineCurrentLookupKey() {
// 从自定义的位置获取数据源标识
return DynamicDataSourceHolder.getDataSource();
}

}

DataSource注解:

package com.yryz.qshop.modules.dynamiclink.inter;

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

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value();
}

拦截器

DataSourceAspect.java

package com.yryz.qshop.modules.dynamiclink.aspect;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import com.yryz.qshop.modules.dynamiclink.DynamicDataSourceHolder;
import com.yryz.qshop.modules.dynamiclink.inter.DataSource;

public class DataSourceAspect {

/**
* 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
*
* @param point
* @throws Exception
*/
public void intercept(JoinPoint point) throws Exception {
Class<?> target = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
// 默认使用目标类型的注解,如果没有则使用其实现接口的注解
for (Class<?> clazz : target.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target, signature.getMethod());
}

/**
* 提取目标对象方法注解和类型注解中的数据源标识
*
* @param clazz
* @param method
*/
private void resolveDataSource(Class<?> clazz, Method method) {
try {
Class<?>[] types = method.getParameterTypes();
// 默认使用类型注解
if (clazz.isAnnotationPresent(DataSource.class)) {
DataSource source = clazz.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value());
}
// 方法注解可以覆盖类型注解
Method m = clazz.getMethod(method.getName(), types);
if (m != null && m.isAnnotationPresent(DataSource.class)) {
DataSource source = m.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value());
}
} catch (Exception e) {
System.out.println(clazz + ":" + e.getMessage());
}
}

}

spring 配置多数据源 (案例)的更多相关文章

  1. Spring配置c3p0数据源时出错报:java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector

    今天在使用Spring配置c3p0数据源时,使用的数据库是mysql,服务器是tomcat,运行时报了一个 java.lang.NoClassDefFoundError: com/mchange/v2 ...

  2. Spring配置动态数据源-读写分离和多数据源

    在现在互联网系统中,随着用户量的增长,单数据源通常无法满足系统的负载要求.因此为了解决用户量增长带来的压力,在数据库层面会采用读写分离技术和数据库拆分等技术.读写分离就是就是一个Master数据库,多 ...

  3. Spring配置多数据源错误总结

    由于系统需要调用多个数据源包含mysql,sqlServe和Oracle,所以要在Spring的xml文件中配置多数据源,一下是配置过程中常见的错误: 1.配置的是mysql的数据源,却报oracle ...

  4. Spring配置DataSource数据源

    在Spring框架中有例如以下3种获得DataSource对象的方法: 1.从JNDI获得DataSource. 2.从第三方的连接池获得DataSource. 3.使用DriverManagerDa ...

  5. 使用Spring配置动态数据源实现读写分离

    最近搭建的一个项目需要实现数据源的读写分离,在这里将代码进行分享,以供参考.关键词:DataSource .AbstractRoutingDataSource.AOP 首先是配置数据源 <!-- ...

  6. spring配置多数据源——mybatis

    这篇文章是配置mybatis多数据源文章,如果是hibernate的话也是没什么影响,配置都是差不多的. 在这家公司上班差不多一星期了,不小心点开配置文件一看这项目配置了两个数据源,蒙了. 之后上网查 ...

  7. Spring 配置JNDI数据源

    1.Spring 提供的JNDI调用类. 2.使用weblogic进行部署项目,所以使用WebLogicNativeJdbcExtrator类进行配置. 3.配置完数据源后配置sessionFacto ...

  8. 使用 Spring 配置动态数据源实现读写分离

    关键词:DataSource .AbstractRoutingDataSource.AOP 首先是配置数据源 <!--读数据源配置--><bean id="readData ...

  9. 阿里P7教你如何使用 Spring 配置动态数据源实现读写分离

    最近搭建的一个项目需要实现数据源的读写分离,在这里将代码进行分享,以供参考. 关键词:DataSource .AbstractRoutingDataSource.AOP 首先是配置数据源 <!- ...

随机推荐

  1. Sublime Text3配置SublimeREPL快捷键的方法(Python)

    因为用sublime运行python,如果有input()函数,ctrl+b是不能输入数据的,所以下载安装了sublimeREPL进行调试. 但是sublimeREPL没有自定义快捷键,所以只有自己设 ...

  2. 树形结构JSON的实现方法

    在Web应用程序开发领域,基于Ajax技术的JavaScript树形控件已经被广泛使用,它用来在Html页面上展现具有层次结构的数据项.目前市场上常见的JavaScript框架及组件库中均包含自己的树 ...

  3. WCF信道绑定代码

    监听端创建信道Listener,代码 using System; using System.Collections.Generic; using System.Linq; using System.T ...

  4. 汕头市队赛 SRM1X T1

    木之本樱 背景 “西瓜是可以种在树上的!”——木之本樱 描述 空地上,一排排的西瓜树拔地而起. 魔法世界里,空地是无限大的.所有的树排成了n条直线,每条直线也是向左右两端无限延伸的. 由于自己姓木(之 ...

  5. (转)cygwin个性化配置

    http://blog.cong.co/cygwin.html#%E5%AE%9A%E4%B9%89%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F配置 cygwin 中的服务 ...

  6. 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】

    转自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] ...

  7. Flex接收51单片机发送过来的16进制数据转换为String

    private static function toHex(bytes:ByteArray):String{ var pos:int =bytes.position; bytes.position=0 ...

  8. 将log4j2的配置文件log4j2.xml拆分成多个xml文件

    在日常的项目开发中,我们可能会使用log4j2分离系统日志与业务日志 ,这样一来,log4j2.xml 这个配置文件可能就会变得非常臃肿.庞大,那么我们可以将这个文件拆分成多个配置文件吗? 答案是肯定 ...

  9. 文件夹操作-DirectoryInfo类

    DirectoryInfo类是一个密封类,它可以用来创建.移动.枚举目录和子目录.DirectoryInfo类包括4个属性,可以用来获取目录的名称.父目录等. DirectoryInfo类的属性表 属 ...

  10. 负载均衡技术之-lvs

    LVS简介 Internet的快速增长使多媒体网络服务器面对的访问数量快速增加,服务器需要具备提供大量并发访问服务的能力,因此对于大负载的服务器来讲, CPU.I/O处理能力很快会成为瓶颈.由于单台服 ...