Spring(六)動態代理
阿新 • • 發佈:2018-03-10
AR throws 介紹 自己的 根據 spring implement ret new
在上一篇博客中簡單寫了一下靜態代理,這裏主要講一下動態代理
動態代理主要有兩種
JDK動態代理 CGLIB動態代理
那這兩種代理有什麽區別呢?
(根據自己的理解總結)
1.JDK動態代理
他的特點是:目標對象必須有接口
他的實質是:創建了接口的一個實現類
他運行的時機:程序運行時
2.CGLIB動態代理
他的特點是:在一個類型沒有接口的情況下進行代理
他的實質是:在內存中構建目標類型的子類
他運行的時機是:編譯時
簡單介紹完這兩種代理後,就用個例子具體看怎麽實現動態代理
先做JDK動態代理
準備一個接口ISomeService,接口中有一個方法doSome(),和一個這個接口的實現類SomeServiceImpl,並重寫其中的方法,具體代碼如下
![技術分享圖片](/img/fz.gif)
package demo15; /** * Created by mycom on 2018/3/8. */ public interface ISomeService { public void doSome(); }
![技術分享圖片](/img/fz.gif)
![技術分享圖片](/img/fz.gif)
package demo15; /** * Created by mycom on 2018/3/8. */ public class SomeServiceImpl implements ISomeService { public void doSome() { System.out.println("十點十分的復習"); } }
![技術分享圖片](/img/fz.gif)
使用JDK動態代理不需要再配置文件中進行配置,所以現在直接進行測試,但是測試的時候不能使用單測,而是使用main方法進行測試
![技術分享圖片](/img/fz.gif)
package demo15; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by mycom on 2018/3/8. */ public class Test { public static void main(String[] args) { //首先創建一個接口的實現類 final SomeServiceImpl service=new SomeServiceImpl(); //在調用方法之前想使用動態代理記錄一下日誌,生成動態代理,返回的是接口 ISomeService proxyInstance =(ISomeService) Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(), new InvocationHandler() { /** * * @param proxy 代理對象 * @param method 目標類型的方法 * @param args 方法的參數 * @return * @throws Throwable */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //在這裏記錄一下日誌 System.out.println("before====="); //調用method 的 method.invoke(service,args);//相當於執行目標類型的方法 System.out.println("after======="); return null; } }); //調用動態代理中的方法中的方法 proxyInstance.doSome(); } }
![技術分享圖片](/img/fz.gif)
運行的結果如下
這說明運行時先執行了invoke方法,再執行接口中doSome的方法,實驗成功!
使用CGLIB動態代理實現上述中的運行結果,如何實現呢?
這時就不用再創建接口了,(在這裏我就使用上面的SomeServiceImpl這個類了,這個類中不用做改動),我直接進行測試了,測試還和上面一樣,使用main方法測試,不用配置文件
![技術分享圖片](/img/fz.gif)
package demo09; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * Created by mycom on 2018/3/8. */ public class Test { public static void main(String[] args) { final SomeServiceImpl service=new SomeServiceImpl(); Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(service.getClass()); enhancer.setCallback(new MethodInterceptor() { /** * * @param o 代理對象 * @param method 目標類型的方法 * @param objects 目標方法的參數 * @param methodProxy 代理類的方法 是一個新的參數 * @return * @throws Throwable */ public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("before====="); methodProxy.invoke(service,objects); System.out.println("after====="); return null; } }); SomeServiceImpl proxy =(SomeServiceImpl) enhancer.create(); proxy.doSome(); } }
![技術分享圖片](/img/fz.gif)
運行結果和上面的一樣,這就是兩種方法實現動態代理!
Spring(六)動態代理