为了实现多数据源的动态切换,降低代码耦合度,特地使用了AOP
第一步就要先配置多个数据源支持,下面的这个是我配置的两个数据源和多数据源支持。我这个是没有用mybatis和hibernate的,直接用的jdbcTemplate.
<bean id="dataSourceDemo" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"> <value>${driverClassName}</value></property>
<property name="url"><value>${url}</value></property>
<property name="username"><value>${username}</value></property>
<property name="password"><value>${password}</value></property>
<property name="maxActive"><value>150</value></property>
<property name="maxIdle"> <value>20</value></property>
<property name="removeAbandoned"> <value>true</value></property>
<property name="removeAbandonedTimeout"><value>180</value></property>
<property name="maxWait"><value>10000</value></property>
</bean>
<bean id="dataSourceTarget" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"> <value>${driverClassName}</value></property>
<property name="url"><value>${urlHebi}</value></property>
<property name="username"><value>${usernameHebi}</value></property>
<property name="password"><value>${passwordHebi}</value></property>
<property name="maxActive"><value>150</value></property>
<property name="maxIdle"> <value>20</value></property>
<property name="removeAbandoned"> <value>true</value></property>
<property name="removeAbandonedTimeout"><value>180</value></property>
<property name="maxWait"><value>10000</value></property>
</bean>
<bean id="dynamicDataSource" class="com.simple.dispatch.datasource.DynamicDataSource" >
<!-- 通过key-value的形式来关联数据源 -->
<property name="targetDataSources">
<map>
<entry value-ref="dataSourceLaiya" key="dataSourceLaiyang"></entry>
<entry value-ref="dataSourceChangyuan" key="dataSourceChangyuan"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSourceLaiyang" />
</bean>
<!-- jdbc模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dynamicDataSource" />
</property>
</bean>
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="dynamicDataSource" />
</bean>
第二步自定义一个注解类
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
String name() default "dataSource";
}
第三步配置动态切换类库
public class DynamicDataSource extends AbstractRoutingDataSource{
@Override
protected Object determineCurrentLookupKey() {
// TODO Auto-generated method stub
return CustomerContextHolder.getDBType();
}
}
public class CustomerContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setDBType(String dbType) {
contextHolder.set(dbType);
}
public static String getDBType() {
return contextHolder.get();
}
public static void clearDBType() {
contextHolder.remove();
}
}
第四步配置AOP切面,完成切面通知信息
public class DataSourceAspect {
public void pointcut(){
};
public void before(JoinPoint point)
{
MethodSignature methodSignature = (MethodSignature) point.getSignature();
Object target = point.getTarget();
String method = methodSignature.getName();
try {
Method m = methodSignature.getMethod();
if (m != null &&m.isAnnotationPresent(DataSource.class)) {
DataSource data = m.getAnnotation(DataSource.class);
CustomerContextHolder.setDBType(data.name());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
<bean id="dataSourceAspect" class="com.simple.dispatch.datasource.DataSourceAspect" />
<aop:config>
<aop:aspect id="c" ref="dataSourceAspect">
<aop:pointcut id="allSimpleServiceMethodPO" expression="execution(* com.simple.dispatch.*.service.impl.*.*(..))"/>
<aop:before pointcut-ref="allSimpleServiceMethodPO" method="before"/>
</aop:aspect>
</aop:config>
经过以上步骤就完成了多数据源的动态切换。以下为调用实例:
@DataSource(name="dataSourceDemo")
public List getDemoList() throws Exception{
return null;
}