What:什麼是cglib動态代理?
cglib動态代理是由第三方類庫實作的代理,使用要添加cglib jar包,其代理底層是借助 asm來實作的。( asm是java虛拟機裡面的一種動态生成位元組碼的技術,跟反射是不同的)
How:怎麼實作cglib動态代理呢?
/**
* 目标對象類
*/
public class Target {
public void sayHello() {
System.out.println("你好");
}
}
/**
* cglib動态代理
*/
public class CGLibDynamicProxy implements MethodInterceptor {
//目标對象
private Object target;
/**
* 建立代理對象
* @param target
* @return
*/
public Object getInstance(Object target){
this.target=target;
//用這個類 來建立代理對象(被代理類的子類);并設定父類;設定回調。
//Enhancer該類是cglib jar包中的類
Enhancer enhancer=new Enhancer();
//設定被代理類作為其父類的代理目标
enhancer.setSuperclass(this.target.getClass());
//設定回調方法,當這個代理對象方法被調用時,回調方法intercept()會被執行
enhancer.setCallback(this);
//傳回建立的代理對象
return enhancer.create();
}
/**
* 回調方法
* @param o
* @param method
* @param objects
* @param methodProxy 代理的類的方法(會調用父類被代理的方法)
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object result=null;
before();//前置增強
result=methodProxy.invokeSuper(o,objects);
after();//後置增強
return result;
}
/**
* 在實作方法前可以做的事情
*/
public void before(){
System.out.println("摘下耳機");
}
/**
* 在實作方法後做的事情
*/
public void after(){
System.out.println("戴上耳機");
}
}
/**
* cglib動态代理測試端
*/
public class CglibProxyTest {
public static void main(String[] args) {
CGLibDynamicProxy cgLibDynamicProxy=new CGLibDynamicProxy();
//生成代理對象
Target hello=(Target) cgLibDynamicProxy.getInstance(new Target());
//當調用代理對象的被代理方法時,會自動回調,調用CGLibDynamicProxy代理類中的Intercept()方法
hello.sayHello();
}
}
控制台輸出:
摘下耳機
你好
戴上耳機
Process finished with exit code 0
Why:為什麼要用cglib動态代理?
因為jdk動态代理隻能代理實作了接口的類,如果該目标類沒有實作任何接口,則不能使用jdk動态代理,可以看下WHWW之代理模式(2)-動态代理。而cglib動态代理是針對類來實作的,也就是說這個目标類可以不用實作任何接口,cglib動态代理都可以對該類進行代理。
注:因為cglib動态代理采用的是繼承,是以不能對final修飾的類進行代理
Where:哪些地方使用cglib動态代理?
spring Aop的底層實作就用到cglib動态代理,如果我們要對沒有實作接口的類進行功能擴充時,也可以考慮cglib動态代理。