Java设计模式之代理模式

本文介绍了Java设计模式中的代理模式,包括其概念和主要作用,即在不修改原有对象的基础上扩展功能。文章详细讲解了静态代理和动态代理,动态代理又涉及JDK动态代理和CGLIB动态代理的实现,并通过代码示例展示了如何创建和使用这些代理。代理模式在日常开发中应用广泛,如中介服务、代购等场景。

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

Java设计模式之代理模式

1. 代理模式概述

代理模式是一种比较好理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。

代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后你可以增加一些自定义的操作。

代理模式分为静态代理与动态代理,动态代理又分为jdk动态代理与cglig动态代理。

代理模式使用场景很多,比如买房中介,代购等等都属于代理。

2. 代理模式实现

消费者接口类 Customer

/**
 * 消费者接口类
 *
 * @author 20023262
 * @date 2020/12/11
 * @since 1.0
 */
public interface Customer {
    /**
     * 购物
     */
    void shopping();
}

具体消费者 SingaporeCustomerImpl

/**
 * 具体消费者
 *
 * @author 20023262
 * @date 2020/12/11
 * @since 1.0
 */
public class SingaporeCustomerImpl implements Customer {
    @Override
    public void shopping() {
        System.out.println("【被代理者】 I am SingaporeCustomer");
    }
}

静态代理类 CustomerProxy

/**
 * 静态代理类
 *
 * 静态代理总结:
 * 优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。
 * 缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
 *
 * @author 20023262
 * @date 2020/12/11
 * @since 1.0
 */
public class CustomerProxy implements Customer {
    private Customer customer;

    public CustomerProxy(Customer customer) {
        this.customer = customer;
    }

    @Override
    public void shopping() {
        System.out.println("【静态代理】代购,购物前挑选...");
        customer.shopping();
        System.out.println("【静态代理】代购,购物后检验...");
    }
}

JDK动态代理类 DynamicProxyHandler

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

/**
 * JDK动态代理类
 * 动态代理总结:虽然相对于静态代理,动态代理大大减少了我们的开发任务,同时减少了对业务接口的依赖,降低了耦合度。
 *
 * @author 20023262
 * @date 2020/12/11
 * @since 1.0
 */
public class DynamicProxyHandler implements InvocationHandler {

    private Object object;

    public DynamicProxyHandler(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("【jdk动态代理】代购,购物前挑选...");
        Object result = method.invoke(object, args);
        System.out.println("【jdk动态代理】代购,购物后检验...");
        return result;
    }
}

cglib动态代理类 CglibProxyHandler

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

import java.lang.reflect.Method;

/**
 * cglib动态代理类
 *
 * @author 20023262
 * @date 2020/12/11
 * @since 1.0
 */
public class CglibProxyHandler implements MethodInterceptor {
    private Object target;

    public CglibProxyHandler(Object target) {
        this.target = target;
    }

    /**
     * 代理方法
     */
    public Object getProxyInstance() {
        //1. 工具类
        Enhancer en = new Enhancer();
        //2. 设置父类
        en.setSuperclass(target.getClass());
        //3. 设置回调函数
        en.setCallback((MethodInterceptor) (o, method, args, methodProxy) -> {
            System.out.println("【cglib动态代理】代购,购物前挑选...");
            //Object obj = method.invoke(target, args);
            Object obj = methodProxy.invokeSuper(o, args);
            System.out.println("【cglib动态代理】代购,购物后检验...");
            return obj;
        });
        //4. 创建子类(代理对象)
        return en.create();
    }

    /**
     * 以下方式会抛出异常:Exception in thread "main" java.lang.StackOverflowError
     */
    public Object getInstance(Object object) {
        target = object;
        //增强类对象
        Enhancer enhancer = new Enhancer();
        //设置增强类型
        enhancer.setSuperclass(this.target.getClass());
        //设置回调函数
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("【cglib动态代理】代购,购物前挑选...");
        Object result = proxy.invoke(obj, args);
        System.out.println("【cglib动态代理】代购,购物后检验...");
        return result;
    }
}

代理测试类 ProxyTest

import org.junit.Test;
import java.lang.reflect.Proxy;

/**
 * 代理测试类
 *
 * @author 20023262
 * @date 2020/12/11
 * @since 1.0
 */
public class ProxyTest {

    @Test
    public void proxyTest() {
        System.out.println("--------------原类-------------------------");
        Customer singaporeCustomer = new SingaporeCustomerImpl();
        singaporeCustomer.shopping();

        System.out.println("---------------静态代理类------------------");
        CustomerProxy customerProxy = new CustomerProxy(new SingaporeCustomerImpl());
        customerProxy.shopping();

        System.out.println("---------------jdk动态代理类------------------");
        Customer proxyCustomer = (Customer) Proxy.newProxyInstance(Customer.class.getClassLoader(), new Class[]{Customer.class}, new DynamicProxyHandler(new SingaporeCustomerImpl()));
        proxyCustomer.shopping();

        System.out.println("---------------cglib动态代理类------------------");
        SingaporeCustomerImpl proxyCustomerImpl = (SingaporeCustomerImpl) new CglibProxyHandler(new SingaporeCustomerImpl()).getProxyInstance();
        proxyCustomerImpl.shopping();
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值