1. 程式人生 > >利用 Spring Aop 動態維護多資料來源

利用 Spring Aop 動態維護多資料來源

一、回顧AOP

首先還是回顧下AOP的定義。

在百度百科中看到AOP是這樣的一個定義。在軟體業,AOP為Aspect Oriented Programming的縮寫,

意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟體開發中的一個熱點,也是Spring框架中的一個重要內容,是函數語言程式設計的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。

這裡總結為一句話:通過動態代理的方式來維護系統中無關業務的程式碼。

舉個例子:在任何系統中,都會使用到事務。而事務是無關業務的程式碼,沒有必要在每個業務部分進行相關的程式碼維護。即不符合複用的原則,也不好進行維護。所以一般的情況【非XA事務】,繼承spring或使用註解,或使用配置檔案來交給spring來維護即可,當然這裡界定的都是在非分散式的單個spring容器內維護的事務。

二、配置多資料來源

背景:

專案開發需要配置多個數據源。

  • 1.不同業務需要進行多資料來源的維護

  • 2.相同業務需要進行資料來源讀寫的維護

這裡針對第二種情況進行說明,第一種情況類似。

基本思路:
  1. 通過自定義註解攔截在service層的方法
  2. 通過方法名或者在註解內的value值進行判定
  3. 繼承spring內部的AbstractRoutingDataSource重寫determineCurrentLookupKey方法來設定當前的資料來源
自定義註解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface DataSource { DataSourceType value() default DataSourceType.WRITE; } public enum DataSourceType { WRITE, READ }

RetentionPolicy.RUNTIME 執行時進行 ElementType.METHOD 方法攔截。使用列舉配合自定義註解,更利於維護。

public class DataSourceAspect {

    public void before(JoinPoint point)
    {
        Object target = point.getTarget
(); System.out.println("target name "+target.toString()); String method = point.getSignature().getName(); System.out.println(method); Class<?>[] classz = target.getClass().getInterfaces(); Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()) .getMethod().getParameterTypes(); try { Method m = classz[0].getMethod(method, parameterTypes); if (m != null && m.isAnnotationPresent(DataSource.class)) { DataSource data = m.getAnnotation(DataSource.class); HandleDataSource.clearDataSource(); HandleDataSource.putDataSource(data.value().toString()); } } catch (Exception e) { e.printStackTrace(); } } }

資料來源切面來具體m.getAnnotation(DataSource.class).value()來進行切換。這裡其實也可以使用data.value()來進行正則匹配具體的方法,這樣的情況可以減少在自定義註解上的配置。例如:可以配置符合select、query 等正則字元來進行選擇資料來源。

public class ChooseDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return HandleDataSource.getDataSource();
    }

}

真正用來重寫spring的動態路由的handler。實在是找不到一箇中文詞語能夠代替這個handler,什麼詞都沒有這個感覺。所以這裡請允許我裝一把。

 <bean id="dynamicDataSource" class="com.showme.core.datasource.ChooseDataSource">
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="WRITE" value-ref="dataSourceRW"/>
                <entry key="READ" value-ref="dataSourceR"/>
            </map>

        </property>
        <property name="defaultTargetDataSource" ref="dataSourceRW"/>
    </bean>

其實最核心的配置就是這裡了,其他的都是輔助這個來做的。包括還有aop的配置以及mybatis的xml掃描和基礎的註解支援。

三、可能出現的問題

本文的資料來源切換時通過結合spring以及dubbo來執行的,當程式執行一段時間後呼叫duboo服務時.會出現資料來源切換失敗的問題。

這裡可以使用spring 的@order 註解將spring切換資料來源的方法的使用優先順序調整為-1。這時候就能夠避免這個問題。

四、總結

最近工作的時候,感覺還是遇到瓶頸了。找不到方向和目標,只知道埋頭苦幹沒有思考未來的路。有點轉圈拉磨的感覺。讓我想起溫總理的一句話:仰望星空和腳踏實地。與君共勉。

相關推薦

利用 Spring Aop 動態維護資料來源

一、回顧AOP 首先還是回顧下AOP的定義。 在百度百科中看到AOP是這樣的一個定義。在軟體業,AOP為Aspect Oriented Programming的縮寫, 意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。

利用Spring的AbstractRoutingDataSource解決資料來源的問題

多資料來源問題很常見,例如讀寫分離資料庫配置。 原來的專案出現了新需求,局方要求新增某伺服器用以提供某程式碼,涉及到多資料來源的問題。 研究成果如下: 1、首先配置多個datasource 2、寫一個DynamicDataSource類繼承AbstractR

Spring Boot 動態連線資料來源,主從資料庫

        實際開發場景中,通常情況下單個微服務會配置多個數據源。本文簡單的介紹一下基於Spring boot框架動態連線多資料來源的實現,首先需要將新增的資料來源標籤化,在配置檔案中新增多個數據源,通過引數標籤的方式判斷不同請求對應的資料來源。採用主從配置的方式,配置

Spring Boot + Mybatis + Druid 動態切換資料來源

在大型應用程式中,配置主從資料庫並使用讀寫分離是常見的設計模式。 在Spring應用程式中,要實現讀寫分離,最好不要對現有程式碼進行改動,而是在底層透明地支援。 這樣,就需要我們再一個專案中,配置兩個,乃至多個數據源。 今天,小編先來介紹一下自己配置動態多資料來源的步驟 專案簡介:   編譯器:ID

SpringAOP方式實現資料來源切換

spring動態配置多資料來源,即在大型應用中對資料進行切分,並且採用多個資料庫例項進行管理,這樣可以有效提高系統的水平伸縮性。而這樣的方案就會不同於常見的單一資料例項的方案,這就要程式在執行時根據當時的請求及系統狀態來動態的決定將資料儲存在哪個資料庫例項中,以及從

Spring動態配置資料來源--mysql從庫

一直做了網際網路的小專案,感覺小公司的效能瓶頸主要在資料庫端。大公司沒去過,不清楚~ 一般用mysql資料庫做主從,讀寫分離,減少主庫的壓力。假設1主4從。4個從庫每次的訪問是隨機,壓力平攤。 先把搜來的貼出來。先記錄下,再去code實驗~ 採用spring的Abstr

spring aop動態切換資料來源問題

最近專案需要用到多資料來源,使用aop切換了資料來源始終 還是原來的資料來源,後來感覺是事務引起的,就把 @Transactional註解去掉,就可以切換成功,到網上一查,原來是多資料來源要配置多個事務管理器,配了多個事務管理器後 再把  @Transactional 加上

spring-AOP動態代理

uid turn ret tin ava span pl2 () expand 動態代理 的四個步驟: 通過實現 InvocationHandler 接口創建自己的調用處理器; 通過為 Proxy 類指定 ClassLoader 對象和一組 interface 來創

Spring Boot的Spring-data-jpa的資料來源配置實戰

一 新建pom <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>

spring boot的Jdbc資料來源配置實戰

一 新建依賴 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sprin

Spring AOP動態獲取函式引數中的值

一個簡單的栗子,我們需要記錄一個訂單系統的訂單狀態流轉日誌。為了符合開閉原則,我們只能新加程式碼,隨之引入AOP。AOP的引入是這個功能實現的基礎。接著AOP的作用域是我們要思考的。最方便直觀的當然是註解。所以我們要自定義一個註解。作用於需要記錄日誌的方法上。然後,問題又來了,不通的函式,可能介面引數並不一致

Spring Boot2.0之資料來源分散式事務問題

分散式事務解決方案的問題, 分散式事務產生的原因:   多個不同的服務連線不同的資料來源 ,做分散式事務的管理。   這種情況是連線兩個資料來源的情況,然後事務管理器是這樣的 只管理了test02的這端業務程式碼。所以test02的這個會回滾! 但是test01會入庫哦 這屬於

Spring Boot2.0之資料來源事務管理

結合前面做的小專案,如果我把test01 test02下面的 service 都加了 事務的註解 這樣啟動時候會報錯! 事務管理器裡面不能有兩個事務!!!! 這時候需要用  @Transactional(transactionManager="test1TransactionManager")

spring boot 2.0資料來源案例

  主資料來源配置 @Configuration @MapperScan(basePackages = "com.somta.springboot.dao.master", sqlSessionTemplateRef = "masterSqlSessionTemplate

Spring Boot之JdbcTemplate資料來源配置與使用

之前在介紹使用JdbcTemplate和Spring-data-jpa時,都使用了單資料來源。在單資料來源的情況下,Spring Boot的配置非常簡單,只需要在application.properties檔案中配置連線引數即可。但是往往隨著業務量發展,我們通常會進行資料庫拆分或是引入其他資料庫,從而我們需要

Spring Boot整合Hibernate(資料來源配置).md

配置資料來源: 定義兩個DataSource用來讀取application.properties中的不同配置: @Configuration public class DataSourceConfig { @Bean(

spring boot+mybatis+druid 資料來源庫分散式事務

廢話不多說,首先貼配置檔案,需要引入pomxml <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter&l

spring boot+mybatis+druid 資料來源配置

application.yml(application.properties)配置: spring: datasource: druid: type: com.alibaba.druid.pool.xa.DruidXADataSource

Spring使用Spring的AbstractRoutingDataSource實現資料來源切換

最近因為專案需要在做兩個專案間資料同步的需求,具體是專案1的資料通過訊息佇列同步到專案2中,因為這個更新操作還涉及到更新多個庫的資料,所以就需要多資料來源切換的操作。下面就講講在Spring中如何進行資料來源切換。這裡是使用AbstractRoutingDataSource類

spring AOP 動態代理原理 虛擬碼

  一.AOP的概念          在軟體業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。AOP是