參考:http://wiki.jikexueyuan.com/project/ssh-noob-learning/dynamic-proxy.html(from極客學院)
一、介紹
Spring的動態代理有兩種:一是JDK的動態代理;另一個是cglib動態代理(通過修改字節碼來實現代理)。
今天主要討論JDK動態代理的方式。
JDK的代理方式主要就是通過反射跟動態編譯來實現的,主要搭配InvocationHandler和Proxy來實現,下面的例子中使用了兩層代理(即代理上加了一層代理)。
二、實例
1. 公共接口
1 package com.tgb.proxy; 2 3 public interface UserMgr { 4 5 void addUser(); 6 void delUser(); 7 8 }
2. 實現類
1 package com.tgb.proxy; 2 3 public class UserMgrImpl implements UserMgr { 4 5 @Override 6 public void addUser() { 7 System.out.println("添加用戶...."); 8 } 9 10 @Override 11 public void delUser() { 12 System.out.println("刪除用戶....."); 13 } 14 15 }
3. TransactionHandler(InvocationHandler的實現)
1 package com.tgb.proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 6 public class TransactionHandler implements InvocationHandler { 7 8 private Object target; 9 10 public TransactionHandler(Object target){ 11 super(); 12 this.target = target; 13 } 14 15 @Override 16 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 17 18 System.out.println("開啟事務..."); 19 20 method.invoke(target); 21 22 System.out.println("提交事務..."); 23 24 return null; 25 } 26 27 28 }
4. TimeHandler(InvocationHandler的實現)
1 package com.tgb.proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.util.Calendar; 6 7 public class TimeHandler implements InvocationHandler { 8 9 private Object target; 10 11 public TimeHandler(Object target) { 12 super(); 13 this.target = target; 14 } 15 16 @Override 17 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 18 19 Calendar calendar = Calendar.getInstance(); 20 21 System.out.println("start time:" + calendar.get(Calendar.HOUR_OF_DAY)); 22 23 method.invoke(target); 24 25 System.out.println("end time:" + calendar.get(Calendar.HOUR_OF_DAY)); 26 27 return null; 28 } 29 30 }
5. 測試類
1 package com.tgb.proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Proxy; 5 6 public class Client { 7 8 public static void main(String[] args) { 9 10 UserMgr userMgr = new UserMgrImpl(); 11 12 // 1.第一層代理----------通過動態代理,添加事務處理 13 InvocationHandler handler = new TransactionHandler(userMgr); 14 UserMgr userMgrProxy = (UserMgr) Proxy.newProxyInstance(userMgr.getClass().getClassLoader(), 15 userMgr.getClass().getInterfaces(), handler); 16 17 // 2.第二層代理----------通過動態代理,添加時間處理 18 InvocationHandler handler2 = new TimeHandler(userMgrProxy); 19 UserMgr userMgrProxy2 = (UserMgr) Proxy.newProxyInstance(userMgrProxy.getClass().getClassLoader(), 20 userMgrProxy.getClass().getInterfaces(), handler2); 21 22 userMgrProxy2.addUser(); 23 24 System.out.println("========================================"); 25 26 userMgrProxy2.delUser(); 27 28 } 29 }
輸出結果:
start time:Tue Aug 09 23:54:54 CST 2016 開啟事務... 添加用戶.... 提交事務... end time:Tue Aug 09 23:54:54 CST 2016 ======================================== start time:Tue Aug 09 23:54:54 CST 2016 開啟事務... 刪除用戶..... 提交事務... end time:Tue Aug 09 23:54:54 CST 2016