最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Spring AOP 實現(xiàn)主從讀寫分離

 更新時間:2017年03月02日 16:25:45   作者:Mafly  
本篇文章主要介紹了Spring AOP 實現(xiàn)主從讀寫分離,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

深刻討論為什么要讀寫分離?

為了服務(wù)器承載更多的用戶?提升了網(wǎng)站的響應(yīng)速度?分攤數(shù)據(jù)庫服務(wù)器的壓力?就是為了雙機熱備又不想浪費備份服務(wù)器?上面這些回答,我認為都不是錯誤的,但也都不是完全正確的?!缸x寫分離」并不是多么神奇的東西,也帶不來多么大的性能提升,也許更多的作用的就是數(shù)據(jù)安全的備份吧。

從一個庫到讀寫分離,從理論上對服務(wù)器壓力來說是會帶來一倍的性能提升,但你仔細思考一下,你的應(yīng)用服務(wù)器真的很需要這一倍的提升么?那倒不如你去試著在服務(wù)器使用一下緩存系統(tǒng),如 Memcached、Redis 這些分布式緩存,那性能可能是幾十倍的提升。而且,在服務(wù)器硬件異常強悍及性能廉價的今天,完全更沒必要了,所以,在今天,我認為它更多的職責(zé)就是為了數(shù)據(jù)安全而設(shè)計的,同時又提升了一些性能,這樣也挺好。

可能我們更應(yīng)該稱之為主從分離。

利用 AOP 實現(xiàn)讀寫分離

讀寫分離方式很簡單,就是在你讀數(shù)據(jù)是去連接從庫,在你寫數(shù)據(jù)的時候去連接主庫,具體代碼實現(xiàn)當(dāng)然就是連接時候去操作了,這沒什么難度,在代碼里寫就是了。可是,有追求的程序猿都是不是這么解決問題的呢!

 其實通過上篇的 Spring AOP 攔截器的基本實現(xiàn) 我們知道 AOP 可以實現(xiàn)在方法開始執(zhí)行前后插入執(zhí)行我們想要的代碼,那這樣,我們是不是可以在執(zhí)行數(shù)據(jù)庫操作前根據(jù)業(yè)務(wù)來動態(tài)切換數(shù)據(jù)源呢?

思考一下這個方式理論上好像是可行的,這種方式首先不需要在業(yè)務(wù)代碼中去做切換,二是可能以后我們不需要讀寫分離了,把 AOP 切換的代碼去掉就行了,三是可能就是拓展性好了。

等不了了,開始擼代碼

你可能想深入的了解的話,我這里給你幾個程序里用到的關(guān)鍵字enum(枚舉)annotation(自定義注解)、JoinPoint(注入點)、AbstractRoutingDataSource(數(shù)據(jù)源接口子類),你理解了這些就知道了,其實你并不需要深入某些深層的東西,了解下即可。

一、建立JdbcContextHolder.java類

public class JdbcContextHolder {

 private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

 public static void setJdbcType(String jdbcType) {
 contextHolder.set(jdbcType);
 }

 public static void setSlave() {
 setJdbcType("slave");
 }

 public static void setMaster() {
 clearJdbcType();
 }

 public static String getJdbcType() {
 return (String) contextHolder.get();
 }

 public static void clearJdbcType() {
 contextHolder.remove();
 }
}

這個類的作用就是用來設(shè)置、獲取數(shù)據(jù)源連接

二、新建DynamicDataSource.java類,繼承于AbstractRoutingDataSource

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import cn.mayongfa.common.JdbcContextHolder;

public class DynamicDataSource extends AbstractRoutingDataSource {

 @Override
 protected Object determineCurrentLookupKey() {
 // 獲取當(dāng)前數(shù)據(jù)源連接
 return JdbcContextHolder.getJdbcType();
 }
}

通過研究,我們知道determineCurrentLookupKey方法是獲取相關(guān)數(shù)據(jù)源連接的,所以重寫determineCurrentLookupKey方法就可以啦,然后我們?nèi)ネㄟ^剛剛我們建立的JdbcContextHolder類去獲取。那怎么設(shè)置呢?

三、建立數(shù)據(jù)源DataSourceType.java枚舉類

public enum DataSourceType {

 //主庫
 Master("master"),

 //從庫
 Slave("slave");

 private DataSourceType(String name) {
 this.name = name;
 }

 private String name;

 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
}

這個枚舉類的作用其實就是為了設(shè)置數(shù)據(jù)源而生的,它的目的就是讓設(shè)置數(shù)據(jù)源時更方便,如絲般順滑。

四、新建DataSource.java Annotation(自定義注解)類

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD)
@Documented
public @interface DataSource { 

 DataSourceType value() default DataSourceType.Master;

} 

自定義注解的意義不再過多討論,一句話來說就是可以讓你在類或方法名上以打標簽的形式讓該方法變得不一樣。具體怎么「不一樣」,這個在于你。

五、新建DataSourceChoose.java數(shù)據(jù)庫切換類

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import cn.mayongfa.common.JdbcContextHolder;

public class DataSourceChoose {

//方法執(zhí)行前
public void before(JoinPoint point){
 Object target = point.getTarget(); 
 String method = point.getSignature().getName(); 
 Class<?>[] classz = target.getClass().getInterfaces(); 
 MethodSignature methodSignature = (MethodSignature)point.getSignature();
 Class<?>[] parameterTypes = methodSignature.getMethod().getParameterTypes();
 try {
  Method m = classz[0].getMethod(method, parameterTypes); 
  if (m!=null && m.isAnnotationPresent(DataSource.class)) { 
  DataSource data = m.getAnnotation(DataSource.class); 
  JdbcContextHolder.clearJdbcType();
  JdbcContextHolder.setJdbcType(data.value().getName());
  } 
 } catch (Exception e) { 
  // TODO: handle exception 
 } 
}
}

這個其實是一個攔截器類,主要作用就是攔截那些方法名上有@DataSource這個自定義注解的,完了根據(jù)獲取注解的value()值,來做相應(yīng)的數(shù)據(jù)源切換。

到這里,整個讀寫分離的分析及業(yè)務(wù)邏輯和具體代碼都完了,以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java中使用sax解析xml的解決方法

    java中使用sax解析xml的解決方法

    本篇文章介紹了,在java中使用sax解析xml的解決方法。需要的朋友參考下
    2013-05-05
  • 詳解Java創(chuàng)建多線程的四種方式以及優(yōu)缺點

    詳解Java創(chuàng)建多線程的四種方式以及優(yōu)缺點

    這篇文章主要介紹了Java創(chuàng)建多線程的四種方式以及優(yōu)缺點,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java編程技巧:if-else優(yōu)化實踐總結(jié)歸納

    Java編程技巧:if-else優(yōu)化實踐總結(jié)歸納

    這篇文章主要介紹了Java中避免過多if-else的幾種方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2021-06-06
  • java判斷ip是否為指定網(wǎng)段示例

    java判斷ip是否為指定網(wǎng)段示例

    這篇文章主要介紹了java判斷ip是否為指定網(wǎng)段示例方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • Spring?Boot使用Schedule實現(xiàn)定時任務(wù)的方法

    Spring?Boot使用Schedule實現(xiàn)定時任務(wù)的方法

    這篇文章主要介紹了Spring?Boot使用Schedule實現(xiàn)定時任務(wù),本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • Java中IO流文件讀取、寫入和復(fù)制的實例

    Java中IO流文件讀取、寫入和復(fù)制的實例

    下面小編就為大家?guī)硪黄狫ava中IO流文件讀取、寫入和復(fù)制的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • Spring Boot+Jpa多數(shù)據(jù)源配置的完整步驟

    Spring Boot+Jpa多數(shù)據(jù)源配置的完整步驟

    這篇文章主要給大家介紹了關(guān)于Spring Boot+Jpa多數(shù)據(jù)源配置的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • 一文搞懂Java的SPI機制(推薦)

    一文搞懂Java的SPI機制(推薦)

    Java定義了一套JDBC的接口,但并未提供具體實現(xiàn)類,而是在不同云廠商提供的數(shù)據(jù)庫實現(xiàn)包。這篇文章給大家介紹Java的SPI機制,感興趣的朋友一起看看吧
    2021-11-11
  • java實現(xiàn)簡易版圖形界面計算器

    java實現(xiàn)簡易版圖形界面計算器

    這篇文章主要為大家詳細介紹了java實現(xiàn)簡易版圖形界面計算器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • SpringBoot項目中使用騰訊云發(fā)送短信的實現(xiàn)

    SpringBoot項目中使用騰訊云發(fā)送短信的實現(xiàn)

    本文主要介紹了SpringBoot項目中使用騰訊云發(fā)送短信的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04

最新評論

巴楚县| 大丰市| 余江县| 秦安县| 高陵县| 方山县| 汪清县| 常熟市| 横山县| 福泉市| 聊城市| 恭城| 梁河县| 南阳市| 伊通| 乃东县| 赤壁市| 芦溪县| 玉龙| 宁国市| 略阳县| 津南区| 莱西市| 南康市| 汉川市| 竹山县| 曲松县| 叙永县| 财经| 中方县| 婺源县| 舟山市| 东乡县| 静安区| 天峨县| 南岸区| 璧山县| 高州市| 华安县| 姜堰市| 车险|