Java代理模式及應用(三)Cglib實現
阿新 • • 發佈:2019-01-10
前一節所說的靜態代理和動態代理模式都是要求目標物件是實現一個介面的目標物件,但是有時候目標物件只是一個單獨的物件,並沒有實現任何的介面,這個時候就可以使用以目標物件子類的方式類實現代理,這種方法就叫做:Cglib代理
1.Cglib說明
Cglib代理,也叫作子類代理,它是在記憶體中構建一個子類物件從而實現對目標物件功能的擴充套件。
Cglib是一個強大的高效能的程式碼生成包,它可以在執行期擴充套件java類與實現java介面。它廣泛的被許多AOP的框架使用,例如Spring AOP和synaop,為他們提供方法的interception(攔截)
Cglib包的底層是通過使用一個小而塊的位元組碼處理框架ASM來轉換位元組碼並生成新的類。不鼓勵直接使用ASM,因為它要求你必須對JVM內部結構包括class檔案的格式和指令集都很熟悉。
2.Cglib實現
Clinet:客戶端呼叫
RealSubject、RealSubject2:無繼承,真實角色
CglibSubject:繼承MethodInterceptor,動態代理生成類
Client.java
public class Client {
public static void main(String[] args)
{
CglibSubject cglibSubject = new CglibSubject();
RealSubject realSubject = (RealSubject)cglibSubject.getInstance(new RealSubject());
realSubject.request();
RealSubject2 realSubject2 = (RealSubject2)cglibSubject.getInstance(new RealSubject2());
realSubject2.request2();
}
}
CglibSubject.java
public class CglibSubject implements MethodInterceptor {
private Object sub;
/**
* 建立代理物件
*
* @param sub
* @return
*/
public Object getInstance(Object sub) {
this.sub = sub;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.sub.getClass());
// 回撥方法
enhancer.setCallback(this);
// 建立代理物件
return enhancer.create();
}
@Override
// 回撥方法
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
proxy.invokeSuper(obj, args);
log(sub.getClass().getName());
return null;
}
private void log(String className)
{
System.out.println("代理AOP切入--列印log--"+className);
}
}
RealSubject.java 和 RealSubject2.java
public class RealSubject{
public void request() {
System.out.println("From Real Subject1!");
}
}
public class RealSubject2{
public void request2() {
System.out.println("From Real Subject2!");
}
}
3.Cglib對比
類別 | 靜態代理個數 | 動態代理個數 | Cglib動態代理 |
---|---|---|---|
抽象角色 | n | n | 0 |
真實角色 | n | n | n |
動態代理生成類 | n | 1 | 1 |