欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
aop和aspectj - Java編程

需求和問(wèn)題

  以上篇《AOP是什么》中并發(fā)訪(fǎng)問(wèn)應用為例子:

  多個(gè)訪(fǎng)問(wèn)類(lèi)同時(shí)訪(fǎng)問(wèn)一個(gè)共享數據對象時(shí),每個(gè)訪(fǎng)問(wèn)類(lèi)在訪(fǎng)問(wèn)這個(gè)數據對象時(shí),需要將數據對象上鎖,訪(fǎng)問(wèn)完成后,再實(shí)行解鎖,供其它并發(fā)線(xiàn)程訪(fǎng)問(wèn),這是我們處理并發(fā)訪(fǎng)問(wèn)資源的方式。

  為了實(shí)現這個(gè)需求,先實(shí)現傳統的編程,這里我們假定有一個(gè)寫(xiě)鎖,對數據對象實(shí)行寫(xiě)之前,首先對這個(gè)對象進(jìn)行上寫(xiě)鎖,寫(xiě)操作完畢后,必須釋放寫(xiě)鎖。

  首先,我們需要一個(gè)鎖,這個(gè)鎖可以是數據對象中一個(gè)字段或其它,這里使用Doug Lea的ReentrantWriterPreferenceReadWriteLock作為我們的鎖資源。

import EDU.oswego.cs.dl.util.concurrent.*;

public class Worker extends Thread {

  Data data;

  ReentrantWriterPreferenceReadWriteLock rwl = 
    new ReentrantWriterPreferenceReadWriteLock();

  public boolean createData() {
   try {
    rwl.writeLock().acquire(); //上鎖

    //對data實(shí)行寫(xiě)邏輯操作 
       
   }catch() {
     return false;
   }finally{
     rwl.writeLock().release();  //解鎖
   }
   return true;
  }

  public boolean updateData() {
   try {
    rwl.writeLock().acquire();//上鎖

    //對data實(shí)行寫(xiě)邏輯操作 
       
   }catch() {
     return false;
   }finally{
     rwl.writeLock().release(); //解鎖
   }
   return true;
  }

  public void run() {
    //執行createData()或updateData()
  }
}

假設可能存在另外一個(gè)訪(fǎng)問(wèn)類(lèi),也將對數據對象實(shí)現寫(xiě)操作,代碼如下:

import EDU.oswego.cs.dl.util.concurrent.*;

public class AnotherWorker extends Thread {

  Data data;

  ReentrantWriterPreferenceReadWriteLock rwl = 
    new ReentrantWriterPreferenceReadWriteLock();
  
  public boolean updateData() {
   try {
    rwl.writeLock().acquire();//上鎖

    //對data實(shí)行寫(xiě)邏輯操作 
       
   }catch() {
     return false;
   }finally{
     rwl.writeLock().release(); //解鎖
   }
   return true;
  }

  public void run() {
    //執行updateData()
  }
}

  以上是Java傳統編程的實(shí)現,這種鎖的實(shí)現方式是在每個(gè)具體類(lèi)中實(shí)現,如下圖:

這種實(shí)現方式的缺點(diǎn)很多:

  • 冗余:有很多重復的編碼,如rwl.writeLock().acquire()等;
  • 減少重用:worker的updateData()方法重用性幾乎為零。
  • "數據對象寫(xiě)操作必須使用鎖控制這個(gè)設計目的"不容易顯現,如果更換了一個(gè)新的程序員,他可能編寫(xiě)一段不使用鎖機制就對這個(gè)數據對象寫(xiě)操作的代碼。
  • 如果上述代碼有讀功能,那么我們需要在代碼中實(shí)現先上讀鎖,當需要寫(xiě)時(shí),解讀鎖,再上寫(xiě)鎖等等,如果稍微不小心,上鎖解鎖次序搞錯,系統就隱含大的BUG,這種可能性會(huì )隨著(zhù)這個(gè)數據對象永遠存在下去,系統設計大大的隱患??!

  那么我們使用AOP概念來(lái)重新實(shí)現上述需求,AOP并沒(méi)有什么新花招,只是提供了觀(guān)察問(wèn)題的一個(gè)新視角度。

  這里我們可以?huà)侀_(kāi)新技術(shù)迷人霧障,真正核心還是新思維、新視點(diǎn),人類(lèi)很多問(wèn)題如果換一個(gè)腦筋看待理解,也許結果真的是翻天覆地不一樣啊,所以,作為人自身,首先要重視和你世界觀(guān)和思維方式不一樣的人進(jìn)行交流和溝通。

  現實(shí)生活中有很多"不公平",例如某個(gè)小學(xué)畢業(yè)生成了千萬(wàn)富翁,你就懷疑知識無(wú)用,也許你認為他的機會(huì )好,其實(shí)你可能不知道,他的觀(guān)察問(wèn)題的視角比你獨特,或者他可能會(huì )經(jīng)常換不同的角度來(lái)看待問(wèn)題和解決問(wèn)題,而你由于過(guò)分陷入一個(gè)視角的具體實(shí)現細節中,迷失了真正的方向,要不說(shuō)是讀書(shū)人腦子僵化呢?

  言歸正傳,我們看看AOP是如何從一個(gè)新的視角解決上述問(wèn)題的。

  如果說(shuō)上面代碼在每個(gè)類(lèi)中實(shí)現上鎖或解鎖,類(lèi)似橫向解決方式,那么AOP是從縱向方面來(lái)解決上述問(wèn)題,縱向解決之道示意圖如下:

  AOP把這個(gè)縱向切面cross-cuts稱(chēng)為Aspect(方面),其實(shí)我認為AOP翻譯成面向切面編程比較好,不知哪個(gè)糊涂者因為先行一步,翻譯成“面向方面編程”如此抽象,故弄玄虛。

AspectJ實(shí)現

  下面我們使用AOP的實(shí)現之一AspectJ來(lái)對上述需求改寫(xiě)。AspectJ是AOP最早成熟的Java實(shí)現,它稍微擴展了一下Java語(yǔ)言,增加了一些Keyword等,pointcut的語(yǔ)法如下:

public pointcut 方法名:call(XXXX)

  AspectJ增加了pointcut, call是pointcut類(lèi)型,有關(guān)AspectJ更多基本語(yǔ)法見(jiàn)這里。因為AspectJ使用了一些特別語(yǔ)法,所以Java編譯器就不能用SUN公司提供javac了,必須使用其專(zhuān)門(mén)的編譯器,也許SUN在以后JDK版本中會(huì )引入AOP。

  使用AspectJ如何實(shí)現上圖所謂切面式的編程呢?首先,我們將上圖縱向切面稱(chēng)為Aspect,那么我們建立一個(gè)類(lèi)似Class的Aspect,Java中建立一個(gè)Class代碼如下:

public class MyClass{
  //屬性和方法 ...
}

  同樣,建立一個(gè)Aspect的代碼如下:

public aspect MyAspect{
  //屬性和方法 ...
}

建立一個(gè)Aspect名為L(cháng)ock,代碼如下:

import EDU.oswego.cs.dl.util.concurrent.*;

public aspect Lock {

  ......
  ReentrantWriterPreferenceReadWriteLock rwl = 
    new ReentrantWriterPreferenceReadWriteLock();

  public pointcut writeOperations():
    execution(public boolean Worker.createData()) ||
    execution(public boolean Worker.updateData()) ||
    execution(public boolean AnotherWorker.updateData()) ;


  before() : writeOperations() {
    rwl.writeLock().acquire();//上鎖 advice body
  }

  after() : writeOperations() {
     rwl.writeLock().release(); //解鎖 advice body
  }

  ......
}

  上述代碼關(guān)鍵點(diǎn)是pointcut,意味切入點(diǎn)或觸發(fā)點(diǎn),那么在那些條件下該點(diǎn)會(huì )觸發(fā)呢?是后面紅字標識的一些情況,在執行Worker的createData()方法,Worker的update方法等時(shí)觸發(fā)。

  before代表觸發(fā)之前做什么事情?
  答案是上鎖。

  after代表觸發(fā)之后做什么事情?
  答案是上鎖。

  通過(guò)引入上述aspect,那么Worker代碼可以清潔如下:

public class Worker extends Thread {

  Data data;

  public boolean createData() {
   try {
    //對data實(shí)行寫(xiě)邏輯操作        
   }catch() {
     return false;
   }
   return true;
  }

  public boolean updateData() {
   try {
    //對data實(shí)行寫(xiě)邏輯操作        
   }catch() {
     return false;
   }finally{
   }
   return true;
  }

  public void run() {
    //執行createData()或updateData()
  }
}

  Worker中關(guān)于“鎖”的代碼都不見(jiàn)了,純粹變成了數據操作的主要方法。

AOP術(shù)語(yǔ)

  通過(guò)上例已經(jīng)知道AspectJ如何從切面crosscutting來(lái)解決并發(fā)訪(fǎng)問(wèn)應用需求的,其中最重要的是引入了一套類(lèi)似事件觸發(fā)機制。

  Pointcut類(lèi)似觸發(fā)器,是事件Event發(fā)生源,一旦pointcut被觸發(fā),將會(huì )產(chǎn)生相應的動(dòng)作Action,這部分Action稱(chēng)為Advice。

  Advice在A(yíng)spectJ有三種:before、 after、Around之分,上述aspect Lock代碼中使用了Advice的兩種before和after。

  所以AOP有兩個(gè)基本的術(shù)語(yǔ):Pointcut和Advice。你可以用事件機制的Event和Action來(lái)類(lèi)比理解它們。上述并發(fā)訪(fǎng)問(wèn)應用中pointcut和advice如下圖所示:

小結如下:
advice - 真正的執行代碼,或者說(shuō)關(guān)注的實(shí)現。 類(lèi)似Action。
join point - 代碼中激活advice被執行的觸發(fā)點(diǎn)。
pointcut - 一系列的join point稱(chēng)為pointcut,pointcut有時(shí)代指join point

其中advice部分又有:
Interceptor - 解釋器并沒(méi)有在A(yíng)spectJ出現,在使用JDK動(dòng)態(tài)代理API實(shí)現的AOP框架中使用,解釋有方法調用或對象構造或者字段訪(fǎng)問(wèn)等事件,是調用者和被調用者之間的紐帶,綜合了Decorator/代理模式甚至職責鏈等模式。

Introduction - 修改一個(gè)類(lèi),以增加字段、方法或構造或者執行新的接口,包括Mixin實(shí)現。

例如上述并發(fā)訪(fǎng)問(wèn)應用中,如果想為每個(gè)Data對象生成相應的aspect Lock,那么可以在aspect Lock中人為數據對象增加一個(gè)字段lock,如下:

aspect Lock {

  Data sharedDataInstance;
  Lock( Data d ) {
     sharedDataInstance = d;
  }

  introduce Lock Data.lock; //修改Data類(lèi),增加一字段lock

  advise Data() { //Data構造時(shí)觸發(fā)
     static after {
       //當Data對象生成時(shí),將Data中lock字段賦值為aspect Lock
       //為每個(gè)Data對象生成相應的aspect Lock
       thisObject.lock = new Lock( thisObject );
     }
   }
  ....

}

上述代碼等于在Data類(lèi)中加入一行:

public class Data{
  ......
  Lock lock = new Lock();
  ......
}

 

 

還有其它兩個(gè)涉及AOP代碼運行方式:

weaving - 將aspect代碼插入到相應代碼中的過(guò)程,一般是編譯完成或在運行時(shí)動(dòng)態(tài)完成。取決于具體AOP產(chǎn)品,例如AspectJ是使用特殊編譯器在編譯完成weaving,而nanning、JBoss AOP是使用動(dòng)態(tài)代理API,因此在運行時(shí)動(dòng)態(tài)完成weaving的。
instrumentor - 用來(lái)實(shí)現weaving功能的工具。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
考題詳解|一道面試題比較synchronized和讀寫(xiě)鎖
Java 并發(fā)包中的讀寫(xiě)鎖及其實(shí)現分析 – 碼農網(wǎng)
Spring AOP 常用的四種實(shí)現方式 - Spring之旅 - JavaEye技術(shù)社區
跟我學(xué)aspectj之一
spring代理
Spring AOP示例(注解方式)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久