设计模式中的代理模式

在Java中,代理模式(Proxy Pattern)可以通过静态代理和动态代理两种主要方式实现。

一、静态代理模式

  • 在编译时就已经确定了代理类和被代理类的关系。
  • 代理类和目标对象通常实现相同的接口或继承相同父类。
  • 缺点是对于每个需要代理的目标对象都需要创建一个代理类,这会导致代码膨胀。
java 复制代码
interface Service {
    void performAction();
}

class RealService implements Service {
    @Override
    public void performAction() {
        System.out.println("Performing action in RealService.");
    }
}

class StaticProxy implements Service {
    private final Service realService;

    public StaticProxy(Service realService) {
        this.realService = realService;
    }

    @Override
    public void performAction() {
        // 可以添加前置处理逻辑
        System.out.println("Before performing action.");
        realService.performAction();
        // 可以添加后置处理逻辑
        System.out.println("After performing action.");
    }
}

二、动态代理模式

动态代理允许我们在运行时创建代理对象,而不需要为每一个委托类都编写一个具体的代理类。这提供了更高的灵活性和可扩展性。Java中的动态代理主要分为两种:基于接口的代理和基于子类的代理。

  1. JDK动态代理
  • 使用java.lang.reflect.Proxy类结合InvocationHandler接口,在运行时动态生成代理对象。
  • 只适用于实现了接口的类。
  • 这种方式允许在不修改原代码的情况下为多个接口方法添加通用的行为。
java 复制代码
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxyExample {

    public static void main(String[] args) {
        Service realService = new RealService();
        Service proxyInstance = (Service) Proxy.newProxyInstance(
                realService.getClass().getClassLoader(),
                realService.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("Before " + method.getName());
                        Object result = method.invoke(realService, args);
                        System.out.println("After " + method.getName());
                        return result;
                    }
                });
        proxyInstance.performAction();
    }
}
  1. CGLIB 动态代理
  • 当目标对象没有实现任何接口时,可以使用CGLIB库通过继承的方式生成代理类。
  • CGLIB会在运行时生成目标类的一个子类,并重写其中的方法以插入自定义逻辑。
  • 注意:由于CGLIB是通过继承实现的,因此不能用于代理final类或方法。

使用CGLIB需要引入相应的依赖(如Maven依赖)。

XML 复制代码
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>
java 复制代码
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxyExample {

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RealService.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("Before " + method.getName());
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("After " + method.getName());
                return result;
            }
        });

        Service service = (Service) enhancer.create();
        service.performAction();
    }
}
相关推荐
水宝的滚动歌词6 小时前
设计模式之建造者模式
java·设计模式·建造者模式
Upuping8 小时前
「全网最细 + 实战源码案例」设计模式——外观模式
java·后端·设计模式
渊渟岳10 小时前
掌握设计模式--抽象工厂模式
设计模式
玉面小君13 小时前
C# 设计模式(行为型模式):访问者模式
设计模式·c#·访问者模式
玉面小君13 小时前
C# 设计模式(行为型模式):模板方法模式
设计模式·c#·模板方法模式
工一木子14 小时前
【HeadFirst系列之HeadFirst设计模式】第1天之HeadFirst设计模式开胃菜
java·设计模式·headfirst设计模式
水宝的滚动歌词1 天前
设计模式之适配器模式
设计模式·适配器模式
冷雨夜中漫步1 天前
领域驱动设计(4)—绑定模型与实现
java·开发语言·笔记·后端·设计模式
JINGWHALE11 天前
设计模式 结构型 外观模式(Facade Pattern)与 常见技术框架应用 解析
前端·人工智能·后端·设计模式·性能优化·系统架构·外观模式
JINGWHALE11 天前
设计模式 结构型 代理模式(Proxy Pattern)与 常见技术框架应用 解析
前端·人工智能·后端·设计模式·性能优化·系统架构·代理模式