设计模式 - 代理模式

代理模式

代理模式是一种结构型设计模式,它允许你提供一个代理对象来控制对另一个对象的访问。代理模式可以在不改变原始对象的情况下,增强或控制对原始对象的访问。代理模式通常用于延迟加载、访问控制、日志记录、性能监控等场景。

1.静态代理

静态代理是指在编译时就已经确定代理类和被代理类的关系。静态代理通常需要手动编写代理类,并且代理类和被代理类实现相同的接口或继承相同的父类

java 复制代码
public interface OrderService {
    void save();
}

public class ProxyOrderService implements OrderService {

    // 被代理的对象
    private OrderService orderService;

    public ProxyOrderService(OrderService orderService) {
        this.orderService = orderService;
    }

    // 执行
    public static void main(String[] args) {
        // 创建被代理对象
        OrderService orderService = new OrderServiceImpl();

        // 创建代理对象
        ProxyOrderService proxy = new ProxyOrderService(orderService);

        proxy.save();
    }

    @Override
    public void save() {
        System.out.println("代理前置处理 ...");
        // 执行被代理的对象的方法
        orderService.save();
        System.out.println("代理后置处理 ...");
    }
}

2 动态代理

动态代理是指在运行时动态生成代理类,而不是在编译时手动编写代理类。

2.1 JDK动态代理

JDK动态代理基于Java反射机制实现,它需要被代理对象实现一个接口。

java 复制代码
/**
 * 代理对象 实现 InvocationHandler
 * InvocationHandler 该类做方法拦截所用, 通过此类可以对目标方法进行增强
 */
public class JDKProxyDynamic implements InvocationHandler, Serializable {

    private static final long serialVersionUID = 4431939583048226878L;
    private Object target;

    private Class<?> clazz;

    public JDKProxyDynamic(Class<?> clazz) {
        this.clazz = clazz;
    }

    /**
     * 通过该方法的调用对目标对象进行增强
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调度真实对象之前,方法名: " + method.getName() + ",参数:" + args);

        // Spring框架中使用动态代理,可以从applicationContext里面获取对应的target对象
        if (Objects.isNull(target)) {
            target = clazz.newInstance();
        }
        System.out.println("代理前置处理 ...");
        Object returnResult = method.invoke(target, args);
        System.out.println("代理后置处理 ...");
        return returnResult;
    }

    public static void main(String[] args) {
        // 创建动态代理对象,JDK动态代理只能代理实现接口的类
        OrderService proxyInstance = (OrderService) Proxy.newProxyInstance(
                OrderServiceImpl.class.getClassLoader(),
                OrderServiceImpl.class.getInterfaces(),
                new JDKProxyDynamic(OrderServiceImpl.class)
        );

        // 通过代理对象调用方法
        proxyInstance.save();
    }
}
2.2 CGLIB动态代理

CGLIB动态代理基于ASM字节码生成框架实现,它不需要被代理对象实现接口。CGLIB动态代理是针对类进行代理的,它通过继承目标类创建子类,并重写目标类的方法。

java 复制代码
public class CglibProxy implements MethodInterceptor {
    private static CglibProxy INSTANCE = new CglibProxy();

    private Object target;

    private Class<?> clazz;


    private CglibProxy() {
    }

    public CglibProxy(Class<?> clazz) {
        this.clazz = clazz;
    }

    public static CglibProxy getInstance() {
        return INSTANCE;
    }

    public Object getCglibProxyObject(Object target) {
        // 可以在Spring中获取指定对象,为其创建代理对象,再指定对应的target
        this.clazz = target.getClass();
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    /**
     * @param object 被代理的对象
     * @param method 被代理对象需要执行的方法
     * @param args   被代理对象需要执行的方法 参数
     * @param proxy  触发父类的方法对象
     * @return 被代理对象需要执行的方法 返回值
     * @throws Throwable 抛出的异常信息
     */
    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method execution: " + method.getName());
        Object result = proxy.invokeSuper(object, args);
        System.out.println("After method execution: " + method.getName());
        return result;
    }

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(OrderServiceImpl.class);
        enhancer.setCallback(new CglibProxy());
        OrderService orderService = (OrderService) enhancer.create();
        orderService.save();
    }
}
相关推荐
庄小焱5 小时前
设计模式——中介者设计模式(行为型)
设计模式
无问8176 小时前
Spring AOP:面向切面编程 详解代理模式
java·spring·代理模式·aop
庄小焱7 小时前
设计模式——备忘录设计模式(行为型)
设计模式
庄小焱7 小时前
设计模式——代理设计模式(结构型)
设计模式
哆啦A梦的口袋呀8 小时前
基于Python学习《Head First设计模式》第三章 装饰者模式
python·学习·设计模式
哆啦A梦的口袋呀8 小时前
基于Python学习《Head First设计模式》第五章 单件模式
python·学习·设计模式
季鸢9 小时前
Java设计模式之备忘录模式详解
java·设计模式·备忘录模式
摘星编程12 小时前
工厂方法模式深度解析:从原理到应用实战
java·设计模式·软件工程·工厂方法模式
何中应13 小时前
【设计模式-4.7】行为型——备忘录模式
java·设计模式·备忘录模式
suixinger_lmh1 天前
功能结构整理
unity·设计模式·c#·源代码管理