设计模式:动态代理与静态代理

本文详细介绍了代理模式的概念及其两种主要形式——静态代理与动态代理。通过具体实例展示了如何使用Java实现这两种代理模式,包括使用JDK和CGLIB库进行动态代理的实践。

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

动态代理与静态代理

什么是代理模式

代理模式即一个类(代理类)具有另一个类(被代理类)的所有行为。代理类可以在不更改业务逻辑的情况下扩展被代理类的方法,达到让被代理类更加专注的去处理本身所具有的业务逻辑。
代理模式包括动态代理和静态代理。
静态代理是指在程序运行之前已经存在的代理类及代理实现,即开发者需要在程序运行之前就写好代理类及代理实现。动态代理是指程序运行之后,根据业务逻辑需求,动态的获取、创建被代理类的功能。可以采用JDK、CGLIB来实现动态代理。

静态代理编码实现

创建被代理类接口

package cn.tyrone.java.designpattern.staticproxy;

/**
 * 电脑厂商接口
 * @author shanglishuai
 *
 */
public interface IPCBrand {

    /**
     * 生产电脑
     * @param pcModel 电脑型号
     */
    public void makePC(String pcModel);

    /**
     * 出售电脑
     * @param pcModel 电脑型号
     */
    public void sellPC(String pcModel);
}

创建被代理类

package cn.tyrone.java.designpattern.staticproxy;

/**
 * 联想电脑厂商
 * @author shanglishuai
 *
 */
public class LenevoPCBrand implements IPCBrand {


    @Override
    public void makePC(String pcModel) {
        System.out.println("新研发的的电脑型号:" + pcModel);
    }

    @Override
    public void sellPC(String pcModel) {
        System.out.println("出售最新的电脑型号:" + pcModel);
    }

}

创建代理类

package cn.tyrone.java.designpattern.staticproxy;

/**
 * 联想电脑厂商代理商
 * @author shanglishuai
 *
 */
public class LenevoPCBrandProxy implements IPCBrand {

    // 
    private IPCBrand pcBrand;

    public LenevoPCBrandProxy(IPCBrand pcBrand) {
        this.pcBrand = pcBrand;
    }

    /**
     * 代理联想电脑厂商生产电脑
     */
    @Override
    public void makePC(String pcModel) {
        System.out.println("我是联想电脑厂商的代理商");
        pcBrand.makePC(pcModel);
    }

    /**
     * 代理联想电脑厂商出售电脑
     */
    @Override
    public void sellPC(String pcModel) {
        System.out.println("我是联想电脑厂商的代理商");
        pcBrand.sellPC(pcModel);
    }

}

测试类

package cn.tyrone.java.designpattern.staticproxy;

/**
 * 静态代理测试
 * 
 * @author shanglishuai
 *
 */
public class StaticProxyTest {

    public static void main(String[] args) {
        IPCBrand lenevoPCBrand = new LenevoPCBrand();

        IPCBrand lenevoPCBrandProxy = new LenevoPCBrandProxy(lenevoPCBrand);

        String pcModel = "G470-New";

        lenevoPCBrand.makePC(pcModel);
        lenevoPCBrand.makePC(pcModel);
        System.out.println("\n");
        lenevoPCBrandProxy.makePC(pcModel);
        lenevoPCBrandProxy.makePC(pcModel);

    }

}

JDK方式实现动态代理

创建被代理类接口

package cn.tyrone.java.designpattern.dynamicproxy.jdk;

/**
 * 电脑厂商接口
 * @author shanglishuai
 *
 */
public interface IPCBrand {

    /**
     * 生产电脑
     * @param pcModel 电脑型号
     */
    public void makePC(String pcModel);

    /**
     * 出售电脑
     * @param pcModel 电脑型号
     */
    public void sellPC(String pcModel);
}

创建被代理类

package cn.tyrone.java.designpattern.dynamicproxy.jdk;

/**
 * 联想电脑厂商
 * @author shanglishuai
 *
 */
public class LenevoPCBrand implements IPCBrand {


    @Override
    public void makePC(String pcModel) {
        System.out.println("新研发的的电脑型号:" + pcModel);
    }

    @Override
    public void sellPC(String pcModel) {
        System.out.println("出售最新的电脑型号:" + pcModel);
    }

}

创建JDK动态代理类
JDK动态代理需要实现InvocationHandler接口来实现

package cn.tyrone.java.designpattern.dynamicproxy.jdk;

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

/**
 * 使用jdk实现动态代理方法
 * @author shanglishuai
 *
 */
public class JDKProxy implements InvocationHandler {

    // 真实对象
    private Object target = null;

    /**
     * 建立代理对象与真实对象的代理关系,并返回代理对象
     * @param target 真实对象
     * @return 代理对象
     */
    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
                target.getClass().getInterfaces(), this);
    }

    /**
     * 代理方法逻辑
     * @param proxy 代理对象
     * @param method 当前调度方法
     * @param args 当前方法参数
     * @return 代理结果返回
     * @throws Throwable 异常
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用真实对象的业务方法之前的业务逻辑");
        Object obj = method.invoke(target, args); // 调用真实对象的业务处理方法
        System.out.println("调用真实对象的业务方法之后的业务逻辑");
        System.out.println("\n");
        return obj;
    }

}

JDK动态代理测试类

package cn.tyrone.java.designpattern.dynamicproxy.jdk;

public class JDKProxyTest {
    public static void main(String[] args) {
        IPCBrand pcBrand = new LenevoPCBrand();

        JDKProxy jdkProxy = new JDKProxy();
        // 绑定真实对象
        IPCBrand pcBrandProxy = (IPCBrand)jdkProxy.bind(pcBrand);

        String pcModel = "G470-New";
        pcBrandProxy.makePC(pcModel);
        pcBrandProxy.sellPC(pcModel);
    }
}

采用CGLIB实现动态代理

创建被代理类

package cn.tyrone.java.designpattern.dynamicproxy.cglib;

/**
 * 联想电脑厂商
 * @author shanglishuai
 *
 */
public class LenevoPCBrand  {

    public void makePC(String pcModel) {
        System.out.println("新研发的的电脑型号:" + pcModel);
    }

    public void sellPC(String pcModel) {
        System.out.println("出售最新的电脑型号:" + pcModel);
    }

}

创建CGLIB动态代理类

package cn.tyrone.java.designpattern.dynamicproxy.cglib;

import java.lang.reflect.Method;

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

/**
 * Cglib实现动态代理
 * 使用Cglib实现动态代理需要实现MethodInterceptor接口
 * @author shanglishuai
 *
 */
public class CglibProxy implements MethodInterceptor {

    /**
     * 生成Cglib代理对象
     * @param cls 代理类
     * @return 代理类的代理对象
     */
    public Object getProxy(Class cls) {

        // Cglib enhancer 增加类对象
        Enhancer enhancer = new Enhancer();
        // 设置增强类型
        enhancer.setSuperclass(cls);
        // 定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor接口
        enhancer.setCallback(this);
        // 创建并返回代理对象
        return enhancer.create();
    }

    /**
     * @param proxy 代理对象
     * @param method 方法
     * @param args 方法参数
     * @param methodProxy 方法代理
     * @return result 代理逻辑返回
     * @throws Throwable 异常
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("执行真实对象方法之前可以添加的业务逻辑");
        Object result = methodProxy.invokeSuper(proxy, args);
        System.out.println("执行真实对象方法之后可以添加的业务逻辑\n");
        return result;
    }

}

创建CGLIB动态代理测试类

package cn.tyrone.java.designpattern.dynamicproxy.cglib;

public class CglibProxyTest {
    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        LenevoPCBrand lenevoPCBrandProxy = (LenevoPCBrand)cglibProxy.getProxy(LenevoPCBrand.class);

        String pcModel = "G470-New";

        lenevoPCBrandProxy.makePC(pcModel);
        lenevoPCBrandProxy.sellPC(pcModel);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值