原文地址:https://blog.csdn.net/tanggao1314/article/details/78131834

动态代理是许多框架底层实现的基础,比如Spirng的AOP等,其实弄清楚了动态代理的实现原理,它就没那么神奇了,下面就来通过案例和分析JDK底层源码来揭秘她的神秘面纱,让她一丝不挂地呈现在我们面前,邪恶了。。。

代理模式定义

存在一个代理对象,并且这个代理对象持有真实对象的引用,以实现对真实对象的访问控制。

举个例子,现在公司一般都有VPN,使我们在家也能访问到公司的内网(比如连接公司的数据库等),实现居家办公。这里VPN相当于一个代理,而公司内网相当于被代理对象,也就是真实对象。我们不能直接访问公司内网(真实对象),但是我们通过VPN(代理对象),输入身份信息,确认无误后就可以访问到公司内网。这就是代理模式的作用----控制对象的访问。

代理模式的分类

静态代理

该代理对象持有被代理对象的引用,客户端通过调用代理对象的方法间接实现调用真实对象的方法。代理对象可以在调用真实对象的方法前面加入一些操作:比如身份验证,如果身份验证没有通过,则不能访问真实对象的方法,否则可以调用真实对象的方法;也可以在调用真实对象方法后,加入一些操作,比如记录访问日志。

真实对象接口,提供两个服务方法

/**
 *
 * People 真实对象的接口包含两个方法
 *
 * @author: tanggao
 * @date::2017-9-27 下午3:57:20
 * @version 1.0
 */
public interface People {
    voidsayHello(String msg);

    voidsayBye(String msg);
}

真实对象接口的具体实现

/**
 *
 *Student
 * 真实对象接口的实现
 *@author: tanggao
 *@date::2017-9-27 下午3:58:05
 *@version 1.0
 */
public class Student implements People {

    @Override
    public void sayHello(String msg) {
      System.out.println("Hello "+msg);
    }

    @Override
    public void sayBye(String msg) {
        System.out.println("ByeBye "+msg);
    }

}

代理对象:

/**
 *
 *StaticProxy
 * 代理对象,控制对真实对象的访问控制
 *@author: tanggao
 *@date::2017-9-27 下午4:01:03
 *@version 1.0
 */
public class StaticProxy implements People {
    //真实对象,客户端不能直接访问
    private Peoplepeople;

    publicStaticProxy(){
        this.people=new Student();
    }

    @Override
    public void sayHello(String msg) {
        booleanfriendFlag=true;
        if(friendFlag){
            people.sayHello(msg);
        }
        System.out.println("记录访问日志");

    }

    @Override
    public void sayBye(String msg) {
        booleanfriendFlag=true;
        if(friendFlag){
            people.sayBye(msg);
        }
        System.out.println("记录访问日志");
    }
}

客户端调用及结果:

上面就是静态代理的一个实现,通过静态代理,实现了访问控制,但是在每个真实对象方法之前都加入了访问控制代码来验证权限。如果有很多个方法,则要在每个方法调用前都加入验证权限的代码,这样非常的不灵活且有大量的重复代码,即使把验证权限抽象出来做过方法或者类,但是还是得在每个方法前加一段调用权限验证的代码,比如,一个客户端只用其中的一个方法,但是代理中两个方法都要加入权限控制,要满足其他客户端的调用需求,上面接口中只有两个方法还好,但是如果有上百个方法那岂不是很臃肿。那么有什么办法解决了,那就是动态代理

动态代理