Spring的AOP實現原理之Cglib代理

在Spring的AOP編程中:

如果加入容器的目標對象有實現接口,用JDK代理

如果目標對象沒有實現接口,用Cglib代理,靜態代理和動態代理模式都是要求目標對象是實現一個接口的目標對象,但是有時候目標對象只是一個單獨的對象,並沒有實現任何的接口,這個時候就可以使用以目標對象子類的方式類實現代理,這種方法就叫做:Cglib代理

Cglib代理,也叫作子類代理,它是在內存中構建一個子類對象從而實現對目標對象功能的擴展.

  • JDK的動態代理有一個限制,就是使用動態代理的對象必須實現一個或多個接口,如果想代理沒有實現接口的類,就可以使用Cglib實現.
  • Cglib是一個強大的高性能的代碼生成包,它可以在運行期擴展java類與實現java接口.它廣泛的被許多AOP的框架使用,例如Spring AOP和synaop,為他們提供方法的interception(攔截)
  • Cglib包的底層是通過使用一個小而塊的字節碼處理框架ASM來轉換字節碼並生成新的類.不鼓勵直接使用ASM,因為它要求你必須對JVM內部結構包括class文件的格式和指令集都很熟悉.

Cglib子類代理實現方法:

1.需要引入cglib的jar文件,但是Spring的核心包中已經包括了Cglib功能,所以直接引入pring-core-3.2.5.jar即可.

2.引入功能包後,就可以在內存中動態構建子類

3.代理的類不能為final,否則報錯

4.目標對象的方法如果為final/static,那麼就不會被攔截,即不會執行目標對象額外的業務方法.

代碼示例:

目標對象類:UserDao.java

/**

* 目標對象,沒有實現任何接口

*/

public class UserDao {

public void save() {

System.out.println("----已經保存數據!----");

}

}

Cglib代理工廠:ProxyFactory.java

/**

* Cglib子類代理工廠

* 對UserDao在內存中動態構建一個子類對象

*/

public class ProxyFactory implements MethodInterceptor{

//維護目標對象

private Object target;

public ProxyFactory(Object target) {

this.target = target;

}

//給目標對象創建一個代理對象

public Object getProxyInstance(){

//1.工具類

Enhancer en = new Enhancer();

//2.設置父類

en.setSuperclass(target.getClass());

//3.設置回調函數

en.setCallback(this);

//4.創建子類(代理對象)

return en.create();

}

@Override

public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

System.out.println("開始事務...");

//執行目標對象的方法

Object returnValue = method.invoke(target, args);

System.out.println("提交事務...");

return returnValue;

}

}

測試類:

/**

* 測試類

*/

public class App {

@Test

public void test(){

//目標對象

UserDao target = new UserDao();

//代理對象

UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance();

//執行代理對象的方法

proxy.save();

}

}


分享到:


相關文章: