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)去執行被代理對象中我們原有的方法。一個代理過程就完成了
下面是我針對這整個項目畫的一個圖 應該更加方便理解