设计模式中的代理模式

在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();
    }
}
相关推荐
yangyang_z2 小时前
【C++设计模式之Template Method Pattern】
设计模式
源远流长jerry3 小时前
常用设计模式
设计模式
z26373056114 小时前
六大设计模式--OCP(开闭原则):构建可扩展软件的基石
设计模式·开闭原则
01空间10 小时前
设计模式简述(十八)享元模式
设计模式·享元模式
秋名RG13 小时前
深入理解设计模式之原型模式(Prototype Pattern)
设计模式·原型模式
Yang三少喜欢撸铁16 小时前
【阿里云免费领取域名以及ssl证书,通过Nginx反向代理web服务】
nginx·阿里云·代理模式·ssl
Li小李同学Li1 天前
设计模式【cpp实现版本】
单例模式·设计模式
Blurpath1 天前
什么是静态住宅IP?为什么静态住宅IP能提高注册通过率?
网络·代理模式·ip代理·住宅ip
周努力.1 天前
设计模式之状态模式
设计模式·状态模式
python算法(魔法师版)1 天前
JavaScript性能优化实战,从理论到落地的全面指南
开发语言·性能优化·前端框架·代理模式