JDK动态代理堆栈图详解--干货

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