來源:csdn_wwp 發(fā)布時(shí)間:2018-11-14 11:16:35 閱讀量:961
主要需要解決的問題
1,數(shù)據(jù)源的切換
2,數(shù)據(jù)源切換aop 必須在 spring事務(wù) aop 之前
3,因?yàn)椴煌瑪?shù)據(jù)庫都是 mysql , 所以使用不同dataSource,但同一個(gè)sessionFactory,(如果是不同的數(shù)據(jù)庫,則需要切換 配置多套dataSource,sessionFactory,然后切換sessionFactory)
4,數(shù)據(jù)源切換的切面在 service 層,不能再dao 層,因?yàn)槭聞?wù)的aop 在service層
一, 配置文件內(nèi)容
<?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>
<!-- 導(dǎo)入配置信息 -->
<context:property-placeholder location="classpath:sshTemplate.properties" />
<!-- 導(dǎo)入其它配置文件 -->
<!-- <import resource="task.xml" /> -->
<!-- 第一個(gè)數(shù)據(jù)源 -->
<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>
<!-- 第二個(gè)數(shù)據(jù)源 -->
<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>
<!-- 動(dòng)態(tài)數(shù)據(jù)源 -->
<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>
<!-- 定義事務(wù)管理器(聲明式的事務(wù)) -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" order="5" /> <!-- 設(shè)置order 5,保證在數(shù)據(jù)源切換之后執(zhí)行 -->
<!-- 切換數(shù)據(jù)源 -->
<bean id="dataSourceInterceptor" class="ssh.multipleDataSource.DataSourceInterceptor"></bean>
<aop:config>
<aop:aspect id="dataSourceAspect" ref="dataSourceInterceptor" order="4"><!-- 設(shè)置order 4,保護(hù)證在 事務(wù)之前執(zhí)行 -->
<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
其中數(shù)據(jù)源切換使用的類:
package ssh.multipleDataSource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 動(dòng)態(tài)數(shù)據(jù)源,繼承AbstractRoutingDataSource,并實(shí)現(xiàn)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 {
/**
* 數(shù)據(jù)源切換類 使用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 實(shí)現(xiàn)攔截,選擇數(shù)據(jù)源
* @author wwp
*/
@Component
public class DataSourceInterceptor {
public void switchDataBaseOne(JoinPoint jp){
System.out.println("選擇數(shù)據(jù)源1");
DataBaseContextHolder.setCustomerType("dataSourceOne");
}
public void switchDataBaseTwo(){
System.out.println("選擇數(shù)據(jù)源2");
DataBaseContextHolder.setCustomerType("dataSourceTwo");
}
}