设计模式-代理模式

代理模式

应用场景:不该变源代码,给源代码增加功能。

在Java中,常用的代理有JDK动态代理和cglib动态代理。JDK动态代理由java.lang.reflect包下的Proxy提供的,基于接口生成的代理类,实现对目标类的代理;cglib是由Oracle提供的Java开发工具包,采用字节码技术,直接修改字节码并生成代理子类。

注意:JDK动态代理中,调用方法时其代理类并不知道目标类的具体方法,因此需要通过反射来进行调用,效率很低。

JDK实现动态代理

java 复制代码
public class Person implements IPerson {
    @Override
    public void eat(){
        System.out.println("开始吃饭");
    }
}

1.定义接口,定义需要代理的方法

java 复制代码
public interface IPerson {
    public void eat();
}

2.定义类并创建代理对象

java 复制代码
    public static IPerson createPersonProxy(Person person){
        IPerson iPersonProxy = (IPerson) Proxy.newProxyInstance(PersonProxy.class.getClassLoader()
                , new Class[]{IPerson.class}
                , new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if(method.getName() == "eat"){
                            System.out.println("拿筷子");
                            System.out.println("拿碗");
                        }

                        return method.invoke(person ,args);
                    }
                });
        return iPersonProxy;
    }
}

3.调用代理对象的方法

java 复制代码
public class Demo {
    public static void main(String[] args) {
        Person person = new Person();
        IPerson personProxy = PersonProxy.createPersonProxy(person);
        personProxy.eat();
    }
}

CGLIB实现动态代理

java 复制代码
public class Person{
    public void eat(){
        System.out.println("开始吃饭");
    }
}
java 复制代码
public class PersonProxy implements MethodInterceptor {
    private Enhancer enhancer = new Enhancer();

    public Object getProxy(Class clazz){
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        //通过字节码技术动态创建子类实例
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if(method.getName().equals("eat")){
            System.out.println("拿筷子");
            System.out.println("拿碗");
        }

        //通过代理类调用父类中的方法
        Object result = methodProxy.invokeSuper(o, objects);

        return result;
    }
}
相关推荐
ttod_qzstudio2 小时前
【软考设计模式】命令模式:请求封装与调用接收解耦的精讲
设计模式·命令模式
春卷同学4 小时前
HarmonyOS掌上记账APP开发实践第3篇:接口与实现分离 — MoneyTrack Types.ets 与 Models.ets 的双层设计模式
设计模式
NG47721 小时前
【软件设计与体系结构】-策略设计模式
java·设计模式·软件工程
CaffeinePro1 天前
SOLID五大设计原则:重构优雅代码与架构的底层规范
设计模式·架构
饮茶三千1 天前
电子保函模板编辑器实战二:HTML→FTL 编译转换的设计与实现
前端·vue.js·设计模式
Kel1 天前
Node.js 本质:从全脉络视角理解运行时原理
javascript·设计模式·node.js
码哥字节1 天前
11 万 Star 的 Spec Kit,90% 的工程师只用它解决了 10% 的问题
设计模式·vibe coding·github spec kit
我登哥MVP1 天前
走进 Gang of Four 设计模式:访问者模式
java·设计模式·访问者模式·原型模式
折哥的程序人生 · 物流技术专研1 天前
Java 23 种设计模式:从踩坑到精通 | 番外:代理 vs 装饰器 —— Spring AOP 到底用了哪个?
java·代理模式·装饰器模式·java面试·java设计模式·springaop·从踩坑到精通
ttod_qzstudio1 天前
【软考设计模式】状态模式:状态驱动行为自动转换与代码填空精讲
设计模式·状态模式