为了实现多数据源的动态切换,降低代码耦合度,特地使用了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(); } } }第五步 在spring配置文件中,加入切面影响的切入点<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;}
新闻热点
疑难解答