代理模式为另一个对象提供一个替身或者占位符以控制对这个对象的访问。代理也可以扩展目标对象的功能。
类图:
优点:
1、代理可以过滤掉一些访问,限制对这个对象的访问,起到一个中介的作用。
2、代理类除了是客户类和被代理类的中介之外,我们还可以通过给代理类增加额外的功能来扩展被代理类的功能,这样做我们只需要修改代理类而不需要再修改被代理类类,符合代码设计的开闭原则。代理类主要负责为被代理类预处理消息、过滤消息、把消息转发给被代理类,以及事后对返回结果的处理等。代理类本身并不真正实现服务,而是同过调用被代理类的相关方法,来提供特定的服务。真正的业务功能还是由被代理类来实现,但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的被代理类。
如果按照代理创建的时期来进行分类的话,可以分为两种:静态代理、动态代理。静态代理是由程序员创建或特定工具自动生成源代码,在对其编译。在程序员运行之前,代理类.class文件就已经被创建了。动态代理是在程序运行时通过反射机制动态创建的。
静态代理优点就是上述两个优点。
静态代理缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
动态代理大大减少了我们的开发任务,同时减少了对业务接口的依赖,降低了耦合度。分为JDK动态代理和CGLIB代理。JDK代理只能代理实现接口的类,CGLIB是通过继承实现的代理,所以不能代理final修饰的类。
静态代理实例:
一个Subject接口:
public interface Subject {
public abstract void request();
}
被代理的类:
public class RealSubject implements Subject{
@Override
public void request() {
System.out.println("I am working.");
}
}
代理类:
public class Proxy implements Subject{
Subject subject;
public Proxy(Subject subject){
this.subject=subject;
}
@Override
public void request() {
System.out.println("before...");
subject.request();
System.out.println("after...");
}
}
测试代码:
public class Test {
public static void main(String[] args) {
Subject sb=new Proxy(new RealSubject());
sb.request();
}
}
动态代理实例见如下博客(也就是Spring AOP的实现原理):
https://blog.youkuaiyun.com/karute/article/details/80644625