javascript
Spring AOP基础—JDK动态代理
JDK動態代理主要涉及到java.lang.reflect包中的兩個類:Proxy和InvocationHandler。其中InvocationHandler動態創建一個符合某一接口的實例,生成目標類的代理對象。
首先寫一個接口?ForumService.java?及其實現類?ForumServiceImpl.java ,主要包括二個方法,刪除主題removeTopic 和 刪除?removeForum。代碼如下:
public class ForumServiceImpl implements ForumService {@SuppressWarnings("static-access")public void removeForum(int forumId) {System.out.println("模擬刪除Forum記錄:" + forumId);try {Thread.currentThread().sleep(20);} catch (InterruptedException e) {e.printStackTrace();}}@SuppressWarnings("static-access")public void removeTopic(int topicId) {System.out.println("模擬刪除Topic記錄:" + topicId);try {Thread.currentThread().sleep(40);} catch (InterruptedException e) {e.printStackTrace();}}}現在需要對二個方法的執行效率進行監控,所以創建一個監控方法效率的類?PerformanceMonitor.java 和 一個輔助工具類?MethodPerformance.java。代碼如下:
public class MethodPerformance {private long begin;private long end;private String serviceMethod;public MethodPerformance(String serviceMethod){this.serviceMethod = serviceMethod;this.begin = System.currentTimeMillis();}public void printPerformance(){end = System.currentTimeMillis();long elapse = end - begin;System.out.println(serviceMethod + "花費" + elapse + "毫秒");} } public class PerformanceMonitor {private static ThreadLocal<MethodPerformance> performanceRecord = new ThreadLocal<MethodPerformance>();public static void begin(String method){System.out.println("begin monitor……");MethodPerformance mp = new MethodPerformance(method);performanceRecord.set(mp);}public static void end(){System.out.println("end monitor……");MethodPerformance mp = performanceRecord.get();mp.printPerformance();} }為了將監控方法效率的代碼織入到業務方法?removeTopic 和 removeForum中,我們創建代理類 PerformanceHandler.java,代碼如下:
public class PerformanceHandler implements InvocationHandler {private Object target;public PerformanceHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {PerformanceMonitor.begin(target.getClass().getName() + "." + method.getName());Object obj = method.invoke(target, args);PerformanceMonitor.end();return obj;} }首先,我們實現InvocationHandler接口,該接口定義了一個invoke(Object proxy,Method method,Object[] args)方法,proxy是最終生成的代理實例,一般不會用到;method是被代理目標實例的某個具體方法,通過它可以發起目標實例方法的反射調用;args是通過被代理實例某一個方法的入參,在方法 反射調用時使用。
此外,我們再構造函數里通過target傳入希望被代理的目標對象,在InvocationHandler()接口方法invoke(Object proxy,Method method,Object[] args)里,將目標實例傳給method.invoke()方法,調用目標實例的方法。
下面,我們通過Proxy結合PerformanceHandler創建ForumService接口的代理實例,這個代理實例實現了目標業務類的所有接口,即ForumServiceImpl的ForumService接口。這樣我們就可以按照調用ForumService接口實例相同的方式調用代理實例。代碼如下:
public class TestForumService {public static void main(String[] args) {ForumService target = new ForumServiceImpl();PerformanceHandler handler = new PerformanceHandler(target);ForumService proxy = (ForumService) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);proxy.removeForum(1001);proxy.removeForum(100);} }執行結果如下:
begin monitor……
模擬刪除Forum記錄:1001
end monitor……
com.aop.ForumServiceImpl.removeForum花費16毫秒
begin monitor……
模擬刪除Forum記錄:100
end monitor……
com.aop.ForumServiceImpl.removeForum花費15毫秒
轉載于:https://www.cnblogs.com/fangqi/archive/2012/12/10/2810902.html
總結
以上是生活随笔為你收集整理的Spring AOP基础—JDK动态代理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 防止页面被iframe包含进去
- 下一篇: oracle中通过游标实现查询