首先我们有一个数据源模型命名为User,其中包括username 和 password这两个属性 和他们的set get方法
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)去执行被代理对象中我们原有的方法。一个代理过程就完成了
下面是我针对这整个项目画的一个图 应该更加方便理解