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