JDK動態代理中包含一個類和一個接口:
InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
參數說明:
Object proxy:指被代理的對象。
Method method:要調用的方法
Object[] args:方法調用時所須要的參數 java
接口IFromServicespring
package com.test.service; public interface IFromService { public void removeService(long serviveid) throws Exception; public void modifyService(long serviveid)throws Exception; }
接口實現類 FromServieImplide
package com.test.service; public class FromServieImpl implements IFromService{ @Override public void removeService(long serviveid) throws Exception { // TODO Auto-generated method stub System.out.println("模擬刪除服務ID:"+serviveid); Thread.currentThread().sleep(20); } @Override public void modifyService(long serviveid) throws Exception { // TODO Auto-generated method stub System.out.println("模擬修改服務ID:"+serviveid); Thread.currentThread().sleep(40); } /** * 無接口實現類方法 * @param obj * @throws InterruptedException */ public void addService(Object obj) throws InterruptedException{ System.out.println("模擬新增服務:"+obj); Thread.currentThread().sleep(40); } }
jdk代理類 FromServiceProxy測試
package com.test.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Date; import com.test.utils.DateTimeUtil; /** * jdk 動態代理 * @author Administrator * */ public class FromServiceProxy implements InvocationHandler{ private Object target; /** * 綁定委託類並返回代理類 * @param target * @return */ public Object bind(Object target){ this.target=target; return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } /** * 調用 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object result=null; Date stdate=new Date(); System.out.println("監測 開始時間:"+DateTimeUtil.dateToStrOfDefaulfFormat(stdate)); result=method.invoke(target, args); Date eddate=new Date(); System.out.println("監測 結束時間:"+DateTimeUtil.dateToStrOfDefaulfFormat(eddate)); System.out.println(method.getName()+" 執行耗時:"+(eddate.getTime()-stdate.getTime())+" ms"); return result; } }
測試 TestProxythis
package com.test.proxy; import com.test.service.FromServieImpl; import com.test.service.IFromService; public class TestProxy { public static void main(String[] args) throws Exception { System.out.println("==============jdk proxy================="); FromServiceProxy proxy=new FromServiceProxy(); IFromService service=(IFromService) proxy.bind(new FromServieImpl()); service.removeService(123); service.modifyService(123); } }
輸出以下:spa
==============jdk proxy=================
監測 開始時間:2016-03-24 13:25:48
模擬刪除服務ID:123
監測 結束時間:2016-03-24 13:25:48
removeService 執行耗時:54 ms
監測 開始時間:2016-03-24 13:25:48
模擬修改服務ID:123
監測 結束時間:2016-03-24 13:25:48
modifyService 執行耗時:41 ms
Cglib動態代理
JDK的動態代理機制只能代理實現了接口的類,而不能實現接口的類就不能實現JDK的動態代理,cglib是針對類來實現代理的,他的原理是對指定的目標類生成一個子類,並覆蓋其中方法實現加強,但由於採用的是繼承,因此不能對final修飾的類進行代理。 代理
cglib代理 FromServiceCglibProxycode
package com.test.proxy; import java.lang.reflect.Method; import java.util.Date; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import com.test.utils.DateTimeUtil; /** * cglib 動態代理 * @author Administrator * */ public class FromServiceCglibProxy implements MethodInterceptor{ private Object target; /** * 建立代理對象 * @param target * @return */ public Object getInstance(Object target){ this.target=target; Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(this.target.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Date stdate=new Date(); System.out.println("監測 開始時間:"+DateTimeUtil.dateToStrOfDefaulfFormat(stdate)); proxy.invokeSuper(obj, args); Date eddate=new Date(); System.out.println("監測 結束時間:"+DateTimeUtil.dateToStrOfDefaulfFormat(eddate)); System.out.println(method.getName()+" 執行耗時:"+(eddate.getTime()-stdate.getTime())+" ms"); return null; } }
測試類 TestProxyorm
package com.test.proxy; import com.test.service.FromServieImpl; import com.test.service.IFromService; public class TestProxy { public static void main(String[] args) throws Exception { System.out.println("==============cglib proxy================="); FromServiceCglibProxy cglib=new FromServiceCglibProxy(); FromServieImpl serviceImpl=(FromServieImpl) cglib.getInstance(new FromServieImpl()); serviceImpl.addService("entity"); } }
輸出以下:對象
==============cglib proxy================= 監測 開始時間:2016-03-24 13:25:48 模擬新增服務:entity 監測 結束時間:2016-03-24 13:25:48 addService 執行耗時:65 ms