java中的aop


  剛開始接觸java,總是聽到AOP技術也就是面向切面編程技術,一直很迷糊,它到底是什么,干什么用的,實現原理是什么。今天在這里做個小結。

首先介紹一下AOP技術的由來:

  在我們的業務系統中,有時候需要用業務系統中的”某些代碼”去執行一些公共的動作,比如寫日志、數據庫連接管理、事務管理。那么這樣就需要我們在很多方法中添加重復代碼,這樣使得代碼重復率過高,也不好維護。那么我們想到的是要求每個Action都繼承框架提供好的BaseAction,然后實現excute方法來實現。不過,這樣的方式缺乏靈活性,那就是我們每個Action都需要寫一個類來完成,對於復雜的系統,就需要寫太多這樣的類,因此,我們期望有一種動態的方式來代理操作,於是動態代理機制就出現了,AOP技術其實也是字節碼增強技術,JVM提供的動態代理追根到底也是字節碼增強技術。

 

字節碼增強技術的實現原理:

  字節碼增強技術的實現有兩種方式:

  一種是通過創建原始類的一個子類,也就是動態創建的一個新的類繼承原始類。

  二種是很暴力的方式,直接修改Class字節碼。

 

實現字節碼增強技術的步驟:

  一是在內存中獲取原始的字節碼,通過一些開源的API修改它的byte[]數組,得到一個新的byte[]。

  二將這個新的byte[]數組寫到PermGen區域,也就是加載新的byte[]替換原來的Class字節碼。

 

實現原理和簡介就介紹到這里,下面我們來個例子。

  我們采用的開源api 為javaassit的API來實現字節碼增強技術。

  我們構造一個Transformer方法,它需要實現接口ClassFileTransformer,並實現transform方法,代碼如下:

1、修改class字節碼

public class TestTransformer implements ClassFileTransformer {

 

    @Override

    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,

                            ProtectionDomain protectionDomain, byte[] classfileBuffer)

                                                                                      throws IllegalClassFormatException {

        System.out.println("load class:"+className);

        //判斷是否是需要我們切得目標類

        if("/targetclass".equals(className)){

            CtClass ctClass=ClassPool.getDefault().get(className.replace('/', '.'));

            //獲取需要切得目標方法

            CtMethod ctMethod=ctClass.getDeclaredMethod("display1");

            //插入需要在此之前執行的方法

            ctMethod.insertBefore("name=\"XXXX\";");

            //插入需要在display1之后執行的方法

            ctMethod.insertAfter("System.out.println(value);");

            return ctClass.toBytecode();

        }

        // TODO Auto-generated method stub

        return null;

    }

}

 

2、注冊到Instrumentation中,加載新的class字節碼

  public class InstForTransformer{

   public static void premain(String agentArgs,Instrumentation instP){

     instP.addTransformer(new TestTransformer());

   } 

 }

 

 

如果注冊成功,那么在JVM加載用戶class是,就會調用對應的TestTransformer類的transform方法來獲得修改后的字節碼,達到修改字節碼的目的。發現很多java教程都沒有這方面的講解,那就我來彌補一下吧


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM