设计模式之代理模式ProxyPattern(六)

一、代理模式介绍

1、什么是代理模式?

代理模式是一种结构型设计模式,它允许为其他对象提供一个替代品或占位符,以控制对这个对象的访问。

2、代理模式的角色构成

  • 抽象主题(Subject):定义了真实主题和代理主题的共同接口,这样代理类可以通过实现该接口来代理真实主题。
  • 真实主题(Real Subject):定义了代理所代表的真实对象。
  • 代理(Proxy):持有对真实主题的引用,并实现了与真实主题一样的接口,客户端通过代理来访问真实主题,同时可以在访问真实主题前后进行一些额外操作。

3、代理模式的作用

代理模式的主要目的是控制对对象的访问,可以实现一些额外的功能,比如延迟加载、访问控制、日志记录、性能监控等。代理模式在实际开发中有着广泛的应用,比如远程代理、虚拟代理、保护代理等。总的来说,代理模式提供了一种灵活的方式来控制对对象的访问,并且可以在不改变原始对象的情况下实现一些额外的功能。

二、静态代理模式实例Static Proxy

1、Shopping接口

package com.xu.demo.proxyPattern;

//接口
public interface Shopping {

    void buy();
}

 2、真实类RealShopping

package com.xu.demo.proxyPattern;

//真实类
public class RealShopping implements Shopping {

    @Override
    public void buy() {
        System.out.println("购买商品");
    }
}

 3、静态代理类ShoppingProxy

package com.xu.demo.proxyPattern;

//代理类
public class ShoppingProxy implements Shopping {
    private RealShopping realShopping;

    public ShoppingProxy(RealShopping realShopping) {
        this.realShopping = realShopping;
    }

    @Override
    public void buy() {
        System.out.println("开始记录日志");
        realShopping.buy();
        System.out.println("记录日志完成");
    }
}

4、StaticProxy类测试

package com.xu.demo.proxyPattern;

/**
 * 代理类代理接口的实现类调用接口方法
 */
public class StaticProxy {

    public static void main(String[] args) {
        RealShopping realShopping = new RealShopping();
        ShoppingProxy shoppingProxy = new ShoppingProxy(realShopping);
        shoppingProxy.buy();
    }
}

 运行结果:

二、Java动态代理

动态代理是在运行时动态生成代理类,不需要手动编写代理类。Java种的动态代理主要是使用java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler接口实现。

其中最主要的就是Proxy.newProxyInstance方法,它是用于创建动态代理对象的静态方法。它接受三个参数:

  • ClassLoader:用于加载动态代理类的类加载器。
  • interfaces:要代理的接口数组。
  • InvocationHandler:实现了InvocationHandler接口的对象,用于处理代理对象的方法调用。

1、ShoppingInvocationHandler动态代理处理类

package com.xu.demo.proxyPattern;

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

// 动态代理处理器
public class ShoppingInvocationHandler implements InvocationHandler {

    private Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开始记录日志");
        Object result = method.invoke(target, args);
        System.out.println("记录日志完成");
        return result;
    }
}

 2、动态代理类DynamicShoppingProxy

package com.xu.demo.proxyPattern;

import java.lang.reflect.Proxy;

// 动态代理类
public class DynamicShoppingProxy {

    public static Shopping createProxy(RealShopping realShopping) {
        return (Shopping) Proxy.newProxyInstance(
                realShopping.getClass().getClassLoader(),
                realShopping.getClass().getInterfaces(),
                new ShoppingInvocationHandler(realShopping));
    }
}

 3、JDK代理测试类JavaDynamicProxy

运行:

 三、CGLIB动态代理

CGLIB是一个强大的,高性能的代码生成类库,它可以在运行时扩展Java类。CGLIB代理不要求目标对象实现接口,它通过继承目标类生成代理类。

1、引入CGLIB依赖包,如果你是Spring项目的话Spring框架已经自带了CGLIB动态代理需要的依赖包

       <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>

2、 ShoppingMethodInterceptorCGLIB代理处理器

package com.xu.demo.proxyPattern;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

// CGLIB代理处理器
public class ShoppingMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects,
                            MethodProxy methodProxy) throws Throwable {
        System.out.println("开始记录日志");
        Object result = methodProxy.invokeSuper(o, objects);
        System.out.println("记录日志完成");
        return result;
    }
}

 3、CGLIB代理类CglibShoppingProxy

package com.xu.demo.proxyPattern;

import org.springframework.cglib.proxy.Enhancer;

// CGLIB代理类
public class CglibShoppingProxy {
    public static Shopping createProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RealShopping.class);
        enhancer.setCallback(new ShoppingMethodInterceptor());
        return (Shopping) enhancer.create();
    }
}

 4、CGLIB动态代理测试类CglibDynamicProxy

package com.xu.demo.proxyPattern;

/**
 * CGLIB动态代理测试类
 */
public class CglibDynamicProxy {

    public static void main(String[] args) {
        Shopping cglibProxy = CglibShoppingProxy.createProxy();
        cglibProxy.buy();
    }
}

 运行结果:

  • 22
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易雪寒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值