剛剛學習JAVA的動態代理,是用java.lang.reflect.InvocationHandler類和java.lang.reflect.InvocationHandler介面來實現的。很好用,記錄下來和大家分享一下。
採用自己的代理調用被代理對象的方法,並且可以在方法運行前後加上自己的切面商務邏輯(AOP),比如說日誌、測試方法已耗用時間等等。
其中被代理對象必須是實現了某個介面的類對象;
自己的代理實現InvocationHandler介面,在該介面的invoke方法中實現自己的業務。
在這裡被代理對象實現的介面為UserDao.java
package com.proxy.dao;import com.proxy.model.User;public interface UserDao {/** * 儲存 * @param u */public void saveUser(User u);/** * 刪除 */public void deleteUser();}
被代理對象的類為UserDaoImpl.java,我們是要在運行這裡面的方法時,前面後面加一些邏輯。
package com.proxy.dao.impl;import com.proxy.dao.UserDao;import com.proxy.model.User;public class UserDaoImpl implements UserDao {@Overridepublic void saveUser(User u) {System.out.println("人員儲存~~");}@Overridepublic void deleteUser() {System.out.println("人員刪除~~");}}
自己的代理對象LogHandler.java需實現java.lang.reflect.InvocationHandler介面
其中在invoke方法中定義自己的商務邏輯。
package com.proxy.myproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class LogHandler implements InvocationHandler {/**被代理的對象*/private Object o;public LogHandler(Object o) {super();this.o = o;}/** * 自己的開始業務 * @param str */private void beforeMethod(String str){System.out.println("方法"+str+"()開始~~");}/** * 自己的結束業務 * @param str */private void afterMethod(String str){System.out.println("方法"+str+"()結束~~");}@Overridepublic Object invoke(Object arg0, Method arg1, Object[] arg2)throws Throwable {//自己的業務beforeMethod(arg1.getName());//被代理對象的業務,是通過反射來實現的arg1.invoke(o, arg2);//自己的業務afterMethod(arg1.getName());return null;}}
在使用時需要調用java.lang.reflect.Proxy類的newProxyInstance方法來獲得自己的代理對象,該方法有3個參數分別為
1.獲得這個類對象的載入器與被代理對象相同即可在這裡為UD.getClass().getClassLoader()
2.被代理對象實現的介面在這裡為UD.getClass().getInterfaces()
3.自己的切面業務對象在這裡為IH
package com.proxy.main;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;import com.proxy.dao.UserDao;import com.proxy.dao.impl.UserDaoImpl;import com.proxy.model.User;import com.proxy.myproxy.LogHandler;public class TestMain {public static void main(String[] args) {//被代理對象UserDao UD = new UserDaoImpl();//與切面的業務結合InvocationHandler IH = new LogHandler(UD);//產生我們自己的代理對象,來實現別的切面業務UserDao UserProxy = (UserDao)Proxy.newProxyInstance(UD.getClass().getClassLoader(), UD.getClass().getInterfaces(),IH);UserProxy.saveUser(new User());System.out.println("************************");UserProxy.deleteUser();}}
運行結果為
方法saveUser()開始~~人員儲存~~方法saveUser()結束~~************************方法deleteUser()開始~~人員刪除~~方法deleteUser()結束~~
源碼為:http://download.csdn.net/detail/best198706/5817375