来源:csdn_wwp 发布时间:2018-11-14 11:16:35 阅读量:1070
主要需要解决的问题
1,数据源的切换
2,数据源切换aop 必须在 spring事务 aop 之前
3,因为不同数据库都是 mysql , 所以使用不同dataSource,但同一个sessionFactory,(如果是不同的数据库,则需要切换 配置多套dataSource,sessionFactory,然后切换sessionFactory)
4,数据源切换的切面在 service 层,不能再dao 层,因为事务的aop 在service层
一, 配置文件内容
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"
default-autowire="default" default-lazy-init="false">
<context:component-scan base-package="ssh"></context:component-scan>
<!-- 导入配置信息 -->
<context:property-placeholder location="classpath:sshTemplate.properties" />
<!-- 导入其它配置文件 -->
<!-- <import resource="task.xml" /> -->
<!-- 第一个数据源 -->
<bean id="dataSourceOne" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${db.driver.one}" />
<property name="url" value="${db.url.one}" />
<property name="username" value="${db.username.one}" />
<property name="password" value="${db.password.one}" />
<property name="initialSize" value="5"/>
<property name="maxActive" value="100"/>
<property name="maxWait" value="60000"/>
<property name="minIdle" value="5"/>
</bean>
<!-- 第二个数据源 -->
<bean id="dataSourceTwo" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${db.driver.two}" />
<property name="url" value="${db.url.two}" />
<property name="username" value="${db.username.two}" />
<property name="password" value="${db.password.two}" />
<property name="initialSize" value="5"/>
<property name="maxActive" value="100"/>
<property name="maxWait" value="60000"/>
<property name="minIdle" value="5"/>
</bean>
<!-- 动态数据源 -->
<bean id="dynamicDataSource" class="ssh.multipleDataSource.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSourceOne" key="dataSourceOne"></entry>
<entry value-ref="dataSourceTwo" key="dataSourceTwo"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSourceOne">
</property>
</bean>
<!-- sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
lazy-init="false">
<property name="dataSource" ref="dynamicDataSource" />
<property name="packagesToScan">
<list>
<value>ssh.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQL5InnoDBDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<!-- hibernateTemplate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" >
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 定义事务管理器(声明式的事务) -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" order="5" /> <!-- 设置order 5,保证在数据源切换之后执行 -->
<!-- 切换数据源 -->
<bean id="dataSourceInterceptor" class="ssh.multipleDataSource.DataSourceInterceptor"></bean>
<aop:config>
<aop:aspect id="dataSourceAspect" ref="dataSourceInterceptor" order="4"><!-- 设置order 4,保护证在 事务之前执行 -->
<aop:pointcut expression="execution(* ssh.service.oneService.*.*(..))" id="oneService"/>
<aop:pointcut expression="execution(* ssh.service.twoService.*.*(..))" id="twoService"/>
<aop:before method="switchDataBaseOne" pointcut-ref="oneService"/>
<aop:before method="switchDataBaseTwo" pointcut-ref="twoService"/>
</aop:aspect>
</aop:config>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
其中数据源切换使用的类:
package ssh.multipleDataSource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 动态数据源,继承AbstractRoutingDataSource,并实现determineCurrentLookupKey方法
* @author wwp
*
*/
public class DynamicDataSource extends AbstractRoutingDataSource{
@Override
protected Object determineCurrentLookupKey() {
return DataBaseContextHolder.getCustomerType();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package ssh.multipleDataSource;
/**
* @author wwp
*
*/
public class DataBaseContextHolder {
/**
* 数据源切换类 使用ThreadLocal确保线程安全
*/
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setCustomerType(String customerType) {
contextHolder.set(customerType);
}
public static String getCustomerType() {
return contextHolder.get();
}
public static void clearCustomerType() {
contextHolder.remove();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package ssh.multipleDataSource;
import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Component;
/**
* aop 实现拦截,选择数据源
* @author wwp
*/
@Component
public class DataSourceInterceptor {
public void switchDataBaseOne(JoinPoint jp){
System.out.println("选择数据源1");
DataBaseContextHolder.setCustomerType("dataSourceOne");
}
public void switchDataBaseTwo(){
System.out.println("选择数据源2");
DataBaseContextHolder.setCustomerType("dataSourceTwo");
}
}