首页 > 代码库 > 设计模式--代理模式

设计模式--代理模式

设计模式--代理模式

1.概述


1.1 定义
"Provide a surrogate or placeholder for another object to control access to it"(提供一种代理以控制对这个对象的访问)
代理模式分为动态代理、静态代理,从本质上两者都是产生一个新的类(可以加入一些行为)来代理之前的类。
1.2 分类
静态代理模式:自己手写一个代理类,该代理类会在编译期就生成。这种代理由于不需要再运行期重新生成一个代理类,所以性能较好。但是由于我们需要在代理类中加入一些行为时,需要写的代理较多,且与委托类耦合性较差,代码复用性较差。
动态代理模式:代理类是在运行期生成。相比静态代理,动态代理可以方便的对委托类进行统一处理,代码复用性较好。分为jdk动态代理和cglib动态代理(不懂)。
1.3 应用
代理可以通过延迟实例化(lazily-instantiating),如Hibrenate中的表的连接查询中就有延迟加载;AOP的核心就是使用的动态代理,通过AOP我们可以进行事务处理、日志处理等,

2.详解


2.1 静态代理
技术分享

代码如下:

 1 public interface Subject {
 2     void method();
 3 }
 4 
 5 public class RealSubject implements Subject {
 6     @Override
 7     public void method() {
 8         System.out.println("RealSubject.method()");
 9     }
10 }
11 
12 public class Proxy implements Subject {
13     private Subject realSubject;
14 
15     // 通过构造函数传递被代理者
16     Proxy(Subject realSubject){
17         this.realSubject = realSubject;
18     }
19 
20     // 真正实现代理,在这里我们可以加入一些行为。
21     public void method() {
22         System.out.println("Proxy do something");
23         realSubject.method();
24     }
25 }
26 
27 public class Client {
28     public static void main(String[] args) {
29         Subject realSubject = new RealSubject();
30         Subject proxy = new Proxy(realSubject);
31         proxy.method();
32     }
33 }output:
34 Proxy do something
35 RealSubject.method()

2.2 动态代理
代码如下:

 1 public interface Subject {
 2     void method();
 3 }
 4 
 5 public class RealSubject implements Subject {
 6     @Override
 7     public void method() {
 8         System.out.println("RealSubject.method()");
 9     }
10 }

JDK自带的动态代理实现:
利用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口定义代理类的实现

public class SubjectInvocationHandler implements InvocationHandler {
    private Object target;

    SubjectInvocationHandler(Object target) {
        this.target = target;
    }

    // 在这里实现代理,我们可以通过反射机制加入我们想到的行为
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(Objects.equals(method.getName(), "method")) {
            System.out.println("Proxy do something");
        }
        return method.invoke(target, args);
    }

    // 通过JDK自带的动态代理方法生成代理对象
    public Object getProxy() {
        ClassLoader loader = target.getClass().getClassLoader();
        Class<?>[] interfaces = target.getClass().getInterfaces();
        return Proxy.newProxyInstance(loader, interfaces, this);
    }
}

public class Client {
    public static void main(String[] args) {
        Subject realSuject = new RealSubject();
        SubjectInvocationHandler handler = new SubjectInvocationHandler(realSuject);
        Subject subject = (Subject) handler.getProxy();
        subject.method();
    }
}outpu:
Proxy do something
RealSubject.method()

上面动态代理具体实现还不是很清楚,以后再写。

3. 应用


通过动态代理实现了非常简单的事务处理

 

设计模式--代理模式