配置文件
<!-- 1. 数据源 : DriverManagerDataSource -->
<context:property-placeholder location="classpath:config/jdbc.properties" />
<!-- 数据源1 org.apache.commons.dbcp.BasicDataSource com.alibaba.druid.pool.DruidDataSource -->
<bean id="tDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName">
<value>${jdbc.t.driverClassName}</value>
</property>
<property name="url">
<value>${jdbc.t.url}</value>
</property>
<property name="username">
<value>${jdbc.t.username}</value>
</property>
<property name="password">
<value>${jdbc.t.password}</value>
</property>
<!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="20" />
<!-- 连接池最小空闲 -->
<property name="minIdle" value="0" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<property name="validationQuery"><value>SELECT 1</value></property>
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="25200000" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
<!-- 监控数据库 -->
<!-- <property name="filters" value="stat" /> -->
<property name="filters" value="mergeStat" />
</bean>
<bean id="sDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName">
<value>${jdbc.s.driverClassName}</value>
</property>
<property name="url">
<value>${jdbc.s.url}</value>
</property>
<property name="username">
<value>${jdbc.s.username}</value>
</property>
<property name="password">
<value>${jdbc.s.password}</value>
</property>
<!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="20" />
<!-- 连接池最小空闲 -->
<property name="minIdle" value="0" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<property name="validationQuery"><value>SELECT 1</value></property>
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="25200000" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />
<!-- 监控数据库 -->
<!-- <property name="filters" value="stat" /> -->
<property name="filters" value="mergeStat" />
</bean>
<!--多数据源配置 与 DynamicDataSource 对应-->
<bean id="dataSource" class="com.whb.utils.db.DynamicDataSource">
<property name="defaultTargetDataSource" ref="tDataSource"/>
<property name="targetDataSources">
<map>
<entry key="tDataSource" value-ref="tDataSource"/>
<entry key="sDataSource" value-ref="sDataSource"/>
</map>
</property>
</bean>
<bean id="dataSourceExchange" class="com.whb.utils.db.DataSourceExchange"/>
<!-- 配置druid监控spring jdbc -->
<bean id="druid-stat-interceptor"
class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
</bean>
<bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"
scope="prototype">
<property name="patterns">
<list>
<value>com.whb.service.impl.*</value>
</list>
</property>
</bean>
<aop:config>
<aop:advisor advice-ref="druid-stat-interceptor"
pointcut-ref="druid-stat-pointcut" />
</aop:config>
<!-- 扫描文件(自动将servicec层注入) -->
<context:component-scan base-package="com.whb.service" />
<bean id="exceptionResolver" class="com.whb.exception.CustomSimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="com.whb.exception.SystemException">error/500</prop>
<prop key="com.whb.exception.BusinessException">error/errorpage</prop>
<prop key="java.lang.exception">error/500</prop>
</props>
</property>
</bean>
<!-- <bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/> </bean> <bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property
name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url"
value="jdbc:mysql://192.168.1.101:3038/sumecom_wohaibao" /> <property name="username"
value="root" /> <property name="password" value="binyao02123202" /> </bean> -->
<!-- 2. mybatis的SqlSession的工厂: SqlSessionFactoryBean dataSource:引用数据源 MyBatis定义数据源,同意加载配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:config/mybatis-config.xml" />
<property name="typeAliasesPackage" value="com.whb.model" />
</bean>
<!-- 3. mybatis自动扫描加载Sql映射文件/接口 : MapperScannerConfigurer sqlSessionFactory
basePackage:指定sql映射文件/接口所在的包(自动扫描) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.whb.mapper"></property>
<!--
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property> -->
</bean>
<!-- 对数据源进行事务管理 -->
<!--
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" /> -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="remove*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="delete*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="add*" propagation="REQUIRED" read-only="false"
/>
<tx:method name="insert*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="save*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="update*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="publish*" propagation="REQUIRED"
read-only="false" rollback-for="java.lang.Exception" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
<tx:method name="list*" propagation="SUPPORTS" read-only="true" />
<tx:method name="query*" propagation="SUPPORTS" read-only="true" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="load*" propagation="SUPPORTS" read-only="true" />
<tx:method name="validate*" propagation="SUPPORTS"
read-only="true" />
</tx:attributes>
</tx:advice>
<!--<aop:aspectj-autoproxy proxy-target-class="true"/> -->
<tx:annotation-driven transaction-manager="transactionManager" />
<aop:config>
<aop:pointcut id="pc"
expression="execution(* com.whb.service.impl.*.*(..))" />
<aop:advisor pointcut-ref="pc" advice-ref="txAdvice" order="2" />
<aop:advisor pointcut-ref="pc" advice-ref="dataSourceExchange" order="1" />
</aop:config>
<!-- 日志拦截 -->
<bean id="logAspect" class="com.whb.aspect.LogAspect"></bean>
<!-- 多部分文件上传 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760000" />
<property name="maxInMemorySize" value="40960" />
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
<!-- 默认值如果适合,该项可以不用修改 -->
<context:component-scan base-package="com.whb.task"/>
<!-- 支持异步方法执行 -->
<task:annotation-driven/>
</beans>
JAVA代码
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
String name() default DataSource.wohaibao;
public static String wohaibao = "tDataSource";
public static String appointment = "sDataSource";
}
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
/**
* @Description: 设置数据源类型
* @param dataSource 数据源名称
* @return void
* @throws
*/
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
/**
* @Description: 获取数据源名称
* @param
* @return String
* @throws
*/
public static String getDataSource() {
return contextHolder.get();
}
/**
* @Description: 清除数据源名称
* @param
* @return void
* @throws
*/
public static void clearDataSource() {
contextHolder.remove();
}
}
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
public class DataSourceExchange implements MethodBeforeAdvice,AfterReturningAdvice
{
@Override
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
DataSourceContextHolder.clearDataSource();
}
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
//这里DataSource是自定义的注解,不是java里的DataSource接口
if (method.isAnnotationPresent(DataSource.class))
{
DataSource datasource = method.getAnnotation(DataSource.class);
if(null == datasource || (null != datasource && null == datasource.name()))
DataSourceContextHolder.setDataSource(datasource.wohaibao);
else {
System.out.println(datasource.name());
DataSourceContextHolder.setDataSource(datasource.name());
}
}
// else
// {
// //target是被织入增强处理的目标对象,通过获取getDataSourceName函数来获取target的数据源名称
// DataSourceContextHolder.setDataSource(
// target.getClass.getMethod("getDataSourceName").invoke(target).toString());
// }
}
}
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
}
在 Service层 直接调用
public interface sService {
/**
* 调用多数据源
*/
@DataSource(name = DataSource.appointment)
public sServiceRepView finds(sServiceReqView asrv);
}