public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
接著一個UserDAO接口
public interface UserDAO { public void save(User user); public void delete(); }
在一個實現該接口的類
public class UserDAOImpl implements UserDAO { public void save(User user) { System.out.println("user saved!"); } public void delete() { System.out.println("user deteleted"); } }
接著就是動態代理了 實現invocationHandler的類
public class LogInterceptor implements InvocationHandler { private Object target; public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } public void beforeMethod(Method m) { System.out.println(m.getName() + " start"); } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { beforeMethod(m); m.invoke(target, args); return null; } }
最後我們采取單元測試了 寫一個單元測試
@Test public void testProxy() { UserDAO userDAO = new UserDAOImpl(); LogInterceptor li = new LogInterceptor(); li.setTarget(userDAO); UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li); System.out.println(userDAOProxy.getClass()); System.out.println(userDAOProxy.getClass().getInterfaces()); userDAOProxy.delete(); userDAOProxy.save(new User()); }
當調用這句話的時候 UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li); 我們創建了一個代理對象userDAOProxy 當執行該句的時候 userDAOProxy.delete(); userDAOProxy對象是由Proxy的靜態方法newProxyInstance產生的,該方法後面跟著三個參數分別為 userDAO的類加載器,類的所有接口,和一個實現了invocationHandler 的類LogInterceptor 執行步驟如下 1 執行LogInterceptor對象的invoke方法 2 invoke方法的第一條語句為beforeMethod(m);故跳轉至beforeMethod(m);函數 3執行beforeMethod(m)函數的System.out.println(m.getName() + " start")語句 console中打印出了delete start 在這裡為什麼是delete呢,因為我們上面執行的是userDAOProxy.delete()方法,故m.getName()中的m就是delete方法 beforeMethod(m);執行完畢 4 執行m.invoke(target, args); 如上圖所示直接跳到了UserDAOImpl實例的delete方法 打印台輸出該方法的輸出user deteleted 重新回到invoke方法的 m.invoke(target, args);語句 一個動態代理的過程就結束了。 從這個過程宗我們可以看到 當我們使用動態代理對象的方法時候,首先回去調用invoke方法,該方法有參數Method m,也就是我們使用的方法。 我們在該invoke方法中會加入橫向切面邏輯如上面的例子beforeMethod(Method m)方法,該邏輯執行完後通過調用m.invoke(target, args)去執行被代理對象中我們原有的方法。一個代理過程就完成了 下面是我針對這整個項目畫的一個圖 應該更加方便理解