设计模式-代理模式

Posted 武培轩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式-代理模式相关的知识,希望对你有一定的参考价值。

模式定义

给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用

为什么使用代理

在不改变目标对象方法的情况下对方法进行增强

代理模式实例

静态代理

先创建一个用户接口(UserInterface),声明一个方法

public interface UserInterface {

    void service(String s);
}

创建实现类(UserImpl)

public class UserImpl implements UserInterface {

    @Override
    public void service(String s) {
        System.out.println("我是" + s);
    }
}

创建代理对象类(UserProxy),通过代理类创建实现类实例并访问其方法

public class UserProxy implements UserInterface {

    private UserInterface user;

    public UserProxy(UserImpl user) {
        this.user = user;
    }

    @Override
    public void service(String s) {
        System.out.println("检查身份");
        user.service(s);
        System.out.println("请进门");
    }
}

客户端调用

public class ProxyTest {
    public static void main(String[] args) {
        UserImpl user = new UserImpl();
        UserProxy proxy = new UserProxy(user);
        proxy.service("wupx");
    }
}

输出结果

检查身份
我是wupx
请进门

动态代理

先创建一个User接口

public interface User {

    void code();

    void sleep();
}

创建User的实现类(UserImpl)

public class UserImpl implements User {
    @Override
    public void code() {
        System.out.println("开始敲代码");
    }

    @Override
    public void sleep() {
        System.out.println("开始睡觉");
    }
}

再创建一个代理类(UserImpProxy)

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class UserImpProxy implements InvocationHandler {

    private User user;

    public UserImpProxy(User user) {
        this.user = user;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        Object result;
        if ("code".equals(methodName)) {
            System.out.println("讨论需求");
            result = method.invoke(user, args);
            System.out.println("提测");
        } else if ("sleep".equals(methodName)) {
            System.out.println("洗澡");
            result = method.invoke(user, args);
        } else {
            result = method.invoke(user, args);
        }
        return result;
    }
}

去测试动态代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class TestProxy {
    public static void main(String[] args) {
        UserImpl user = new UserImpl();
        InvocationHandler userProxyHandler = new UserImpProxy(user);
        User userProxy = (User) Proxy.newProxyInstance(user.getClass().getClassLoader(),
                user.getClass().getInterfaces(), userProxyHandler);
        userProxy.code();
        userProxy.sleep();
    }
}

运行结果

讨论需求
开始敲代码
提测
洗澡
开始睡觉

总结

使用Java动态代理的两个重要步骤

  1. 通过实现 InvocationHandler 接口创建自己的调用处理器;
  2. 通过为Proxy类的newProxyInstance方法指定代理类的ClassLoader 对象和代理要实现的interface以及调用处理器InvocationHandler对象来创建动态代理类的对象;

以上是关于设计模式-代理模式的主要内容,如果未能解决你的问题,请参考以下文章

用于从 cloudkit 检索单列的代码模式/片段

设计模式----代理模式

Java设计模式-代理模式之动态代理(附源代码分析)

是否有在单个活动中处理多个片段的 Android 设计模式?

设计模式之代理模式(Proxy)详解及代码示例

代理模式(静态代理动态代理)代码实战(详细)