今天貼出來自己關於spring cglib動態代理的一些理解。小二,先上代碼
package com.suning.sample.aop;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibTest {
/**
* CGLIB動態代理測試類: <br>
* 〈功能詳細描述〉
*
* @param args
* @see [相關類/方法](可選)
* @since [產品/模塊版本](可選)
*/
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
TargetClass proxyClass = (TargetClass)proxy.getProxy(TargetClass.class);
proxyClass.removeTopic(11);
}
}
//目標類
class TargetClass{
public void removeTopic(int topicld){
System.out.println("這裏執行目標對象代碼");
}
}
//創建cglib代理類
class CglibProxy implements MethodInterceptor{
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("嗨,我開始織入代碼");
Object result = proxy.invokeSuper(obj, args);
System.out.println("結束織入標示");
return result;
}
}
1.通過getProxy()方法以及反射機制創建目標類TargetClass的動態代理對象,
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
getProxy()指定了代理對象爲目標類TargetClass的子類,即proxyClass爲TargetClass類的代理類對象。
2.當目標類TargetClass執行removeTopic()方法時,就相當於代理類執行removeTopic()方法。原因:
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("嗨,我開始織入代碼");
Object result = proxy.invokeSuper(obj, args);
System.out.println("結束織入標示");
return result;
}
代理類會攔截所有父類對象方法的調用,在攔截裏面,會植入增強代碼,其中intercept爲CGLIB的Interceptor接口定義的方法,筆者認爲這是實現增強的關鍵,這裏也相當於是切點入口了。這裏研究下intercept參數:
obj: com.suning.sample.aop.TargetClass$$EnhancerByCGLIB$$e0c2e315@8ee016
method: public void com.suning.sample.aop.TargetClass.removeTopic(int)
args: 11
proxy: net.sf.cglib.proxy.MethodProxy@5a67c9
obj是CGLIB創建的目標類的子類,method爲目標類調用方法,args爲方法傳參,proxy爲代理類實例。這裏有個小疑惑,obj和proxy有啥區別呢?求大神解答。
3.運行結果
使用心得:
1.CGLIB是通過建立目標類的子類代理對象,從而執行代碼嵌入的;區別於JDK的通過接口代理。