spring 多数据源-实现
緊接上篇 - 實現
1 創建?DynamicDataSource 繼承?AbstractRoutingDataSource 重寫?determineCurrentLookupKey 方法
??????????????? /**
 ?????????????????*?
 ?????????????????* @Author: ll
 ?????????????????* @Date: 2018年5月29日 上午10:32:32
 ?????????????????* @Description: 多數據源
 ?????????????????* @Version: 1.0?
 ?????????????????*/
 ????????????public class DynamicDataSource extends AbstractRoutingDataSource {
 ???????????? @Override
 ???????????? protected Object determineCurrentLookupKey() {
 ????return DynamicDataSourceHolder.getDatasource();??
 ????????????}
???????????????????}
?
?????????????????/**
 ?????????????????*?
 ?????????????????* @Author: ll
 ?????????????????* @Date: 2018年5月29日 上午10:32:32
 ?????????????????* @Description: 多數據源
 ?????????????????* @Version: 1.0?
 ?????????????????*/
 ????????????public class DynamicDataSource extends AbstractRoutingDataSource {
 ???????????????? @Override
 ????????????????protected Object determineCurrentLookupKey() {
 ????????????return DynamicDataSourceHolder.getDatasource();??
 ???????????????????}
?
????????????????????????}
2 實現?DynamicDataSourceHolder 類
????????/**
 ?????????????*?
 ?????????????* @Author: ll
 ?????????????* @Date: 2018年5月29日 下午10:32:32
 ?????????????* @Description: 多數據源
 ?????????????* @Version: 1.0?
 ?????????????*/
????????????public class DynamicDataSourceHolder {
????????????????????/** 數據源標識保存在線程變量中,避免多線程操作數據源時互相干擾 */??
?
? ????????????????? private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();??
 ? ? ??
 ? ????????????????????? /**?
 ? ? ?????????????????????????* 設置數據源名稱?
 ? ? ?????????????????????????* @param dastsource 數據源名稱?
 ? ????????????????????????? ?*/??
 ? ????????????????? public static void setDatasource(String datasource) {??
 ? ? ? ? ????????????????contextHolder.set(datasource);??
 ? ? ????????????????????}??
 ? ? ??
 ? ????????????? /**?
 ? ? ?????????????* 獲取數據源名稱?
 ? ? ?????????????* @return 數據源名稱?
 ? ????????????? ?*/??
 ? ????????????????? public static String getDatasource() {??
 ? ? ????????????????? ? return contextHolder.get();??
 ? ????????????????? }??
 ? ? ??
 ? ????????????????? /**?
 ? ? ?????????????????* 清除標志?
 ? ? ?????????????????*/??
 ? ????????????????? public static void clearDatasource() {??
 ? ????????????????? ? ? contextHolder.remove();??
 ? ????????????????? }???
?
????????????????}
3 配置多數據源?
?由于代碼較多 在此粘出關鍵代碼?
? ? <bean id="dataSource" class="com.enter.net.frame.datasources.DynamicDataSource">??
 ? ? ? ? <property name="targetDataSources">??
 ? ? ? ? ? ? <map key-type="java.lang.String">??
 ? ? ? ? ? ? ? ? <entry key="fxdataSource" value-ref="fxdataSource"></entry>??
 ? ? ? ? ? ? ? ? <entry key="gblzdataSource" value-ref="gblzdataSource"></entry>??
 ? ? ? ? ? ? </map>??
? ? ? ? </property>??
<!-- 默認使用的數據庫-->
?
? ? ? ? <property name="defaultTargetDataSource" ref="fxdataSource"></property>??
?
? ? </bean>?
4 使用數據源?
本人準備使用注解的方式同時結合spring的AOP??
首先定義個一個注解?DataSource?
/**
 ?*?
 ?* @Author: ll
 ?* @Date: 2018年5月29日 上午10:32:32
 ?* @Description: 多數據源注解
 ?* @Version: 1.0?
 ?*/
 @Target({ElementType.TYPE, ElementType.METHOD})??
 @Retention(RetentionPolicy.RUNTIME)??
 public @interface DataSource {??
 ? ? String value();??
}
2 定義一個切面
/**
 ?*?
 ?* @Author: ll
 ?* @Date: 2018年5月29日 上午10:32:32
 ?* @Description: 多數據源切面
 ?* @Version: 1.0?
 ?*/
 @Aspect
 @Component
 public class DynamicDataSourceInterceptor {
 /**?
 ? ? ?* 攔截目標方法,獲取由@DataSource指定的數據源標識,設置到線程存儲中以便切換數據源?
 ? ? ?* @param point?
 ? ? ?* @throws Exception?
 ? ? ?*/??
 @Before("execution(* com.enter.net.fhbusiness..*Controller.*(..)) or execution(* com.enter.net.system..*Controller.*(..))")
 ? ? public void intercept(JoinPoint point) throws Exception {??
 ? ? ? ? Class<?> target = point.getTarget().getClass();??
 ? ? ? ? MethodSignature signature = (MethodSignature) point.getSignature();??
 ? ? ? ? resolveDataSource(target, signature.getMethod());??
 ? ? }??
 ??
 ? ? /**?
 ? ? ?* 提取目標對象方法注解和類型注解中的數據源標識?
 ? ? ?* @param clazz?
 ? ? ?* @param method?
 ? ? ?*/??
 ? ? private void resolveDataSource(Class<?> clazz, Method method) {??
 ? ? ? ? try {??
 ? ? ? ? ? ? Class<?>[] types = method.getParameterTypes();
 ? ? ? ? ? ? // 默認使用類型注解??
 ? ? ? ? ? ? if (clazz.isAnnotationPresent(DataSource.class)) {??
 ? ? ? ? ? ? ? ? DataSource source = clazz.getAnnotation(DataSource.class);??
 ? ? ? ? ? ? ? ? DynamicDataSourceHolder.setDatasource(source.value());??
 ? ? ? ? ? ? }??
 ? ? ? ? ? ? // 方法注解可以覆蓋類型注解??
 ? ? ? ? ? ? if(types.length!=0) {
 ? ? ? ? ? ? Method m = clazz.getMethod(method.getName(), types);??
 ? ? ? ? ? ? ? ? ?if (m != null && m.isAnnotationPresent(DataSource.class)) {??
 ? ? ? ? ? ? ? ? ? ? ?DataSource source = m.getAnnotation(DataSource.class);??
 ? ? ? ? ? ? ? ? ? ? ?DynamicDataSourceHolder.setDatasource(source.value());??
 ? ? ? ? ? ? ? ? ?}?
 ? ? ? ? ? ? }
 ? ? ? ? } catch (Exception e) {??
 ? ? ? ? ? ? e.printStackTrace();??
 ? ? ? ? }??
 ? ? }??
}
這時候切面 會根據配置的表達式 進行攔截查看是否使用DataSource 注解 如果使用 則獲取注解的值 來設定指定的s
下一篇?https://blog.csdn.net/lilongwangyamin/article/details/80507121?總結
總結
以上是生活随笔為你收集整理的spring 多数据源-实现的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: Prn.txt Con.txt(文件命名
 - 下一篇: LM3S1138驱动函数SysCtlPe