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