纯手写理解设计模式代码之代理模式

本文深入探讨了代理模式在软件设计中的应用,包括静态代理与动态代理的实现方式,如JDK动态代理和CGLIB动态代理,并通过具体示例阐述了它们的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代理模式

代理模式属于结构型设计模式

静态代理模式
package com.demo.proxy;

/**
 * 代理模式
 * 结构型设计模式
 * 三个角色:真实角色Target、代理角色Proxy、消费者Consumer
 * 静态代理模式:
 * 代理角色与真实角色耦合性太高,不适用
 * 但是理解动态代理的第一步
 *下面以房产出租为例:房主、中介、租客一一对应真实、代理、消费者
 */
//租客
interface Person{

    void rent();
}
//房主
class Householder implements Person{

    public void rent() {
        //出租
        System.out.println("出租");
    }

}
//中介
class Agent implements Person{

    private  Person householder;

    public Agent(Householder householer){
        this.householder=householer;
    }

    public void rent() {
        householder.rent();
    }

    public void sign(){
        System.out.println("请签合同");
    }
}
//实例
public class StaticProxy {
    public static void main(String[] args) {
        //实例化代理角色
        Agent agent = new Agent(new Householder());
        //调用代理角色的方法,但实际是调用真实角色的方法
        agent.rent();//出租
        //调用代理角色本身方法
        agent.sign();//请签合同
    }
}

动态代理模式
JDK动态代理
package com.demo.proxy;

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

/**
 * JDK动态代理模式
 * JDK动态代理的实现关键在于java.lang.reflect.Proxy类
 * 其newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)方法是整个JDK动态代理的核心,用于生成指定接口的代理对象。
 * 这个方法有三个参数,ClassLoader表示加载动态生成的代理类的类加载器,interfaces代理类需要实现的接口,InvocationHandler调用处理器InvocationHandler
 */
//同样使用房主、中介、租客三位角色,手写调用处理器
class JDKDynamicProxyHandler implements InvocationHandler {
    private Person householder;

    public JDKDynamicProxyHandler(Person householder) {
        this.householder = householder;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        method.invoke(householder, args);
        after();
        return null;
    }
    public void before(){
        System.out.println("考察一下");
    }
    public void after(){
        System.out.println("决定了");
    }
}

//实例
class JDKDynamicProxy {
    public static void main(String[] args) {
        Person houseHolder = new Householder();
        /**
         * 通过
         * Person.class.getClassLoader() 类加载器   生成代理类的字节码文件
         * new Class[]{Person.class}共同实现Person接口 保证真实角色与代理角色的强一致性
         * new JDKDynamicProxyHandler(houseHolder)手写的调用处理器 最终调用invoke()进行处理
         * 获得代理对象
         */
        Person proxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, new JDKDynamicProxyHandler(houseHolder));
        proxy.rent();

    }
}

CGLIB动态代理
package com.demo.proxy;


import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * CGLIB动态代理
 * JDK动态代理的目标对象必须实现接口,CGLIB动态代理则没有这个限制
 * 它是利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
 */
public class CGLIBDynamicProxy implements MethodInterceptor {


    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //.....增加逻辑
        Object invokeSuper = methodProxy.invokeSuper(o, objects);
        return invokeSuper;
    }

}

class Total {

    public void paly(){
        //........
    }

}

class test{
    public static void main(String[] args) {
        //Enhancer相当于jdk动态代理的Proxy
        Enhancer enhancer = new Enhancer();
        //设置对应的参数
        enhancer.setSuperclass(Total.class);
        enhancer.setCallback(new CGLIBDynamicProxy());
        //正式创建代理类
        Total total = (Total)enhancer.create();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值