Java——動態代理
在靜態代理中,我們在調用target類的時候,都是先拿到proxy類,因為proxy類中將target類作為了成員變數,並且跟target類繼承了一樣的介面,具有相同的方法,所以,在proxy類中,通過調用target類的方法來對目標類方法的執行前後插入特殊操作。
但是靜態代理有倆缺點:1,代理類特別多,每增加一個target類,就要寫一個代理;2,在proxy類中,可能我們需要插入的操作時相同的,這就造成了代碼的重複。
所以,通過引入反射,可以實現動態代理,以對靜態代理進行改進。
/** * @ClassName: LogHandler * @Description: 用於建立代理類 * @author 水田 * @date 2015年12月8日 上午11:17:51 */public class LogHandler implements InvocationHandler { private Object targetObject; public Object newProxyInstance(Object targetObj) {this.targetObject = targetObj;/* * 1,拿到類的classLoader * 2,得到建立的類的介面 * 3,傳入回調invoke方法所在類 * */return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(),targetObj.getClass().getInterfaces(), this); } /* * (非 Javadoc)
Title: invoke
Description:
* * @param proxy * * @param 調用方法資訊 * * @param args:方法的參數數組 * * @return * * @throws Throwable * * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, * java.lang.reflect.Method, java.lang.Object[]) */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } try { // 調用目標類的方法,返回一個object,如果方法沒有傳回值,則返回null method.invoke(targetObject, args); } catch (Exception e) { e.printStackTrace(); throw e; } System.out.println(start----->>> + method.getName()); return method.getName(); } }
使用樣本:
/* 動態代理樣本 */LogHandler logHandler = new LogHandler();UserManager userManager = (UserManager) logHandler.newProxyInstance(new UserManagerImpl());userManager.addUser(2343254, lhc);
我們將target類中被呼叫者法執行前後要插入的操作放在回呼函數invoke方法中,當使用代理類調用對應方法的時候,會直接進入invoke方法這裡,使用method,和invoke第三個參數可以拿到被呼叫者法的資訊。