0
点赞
收藏
分享

微信扫一扫

静态代理、JDK/CGLIB 动态代理

数数扁桃 2022-03-14 阅读 81

静态代理、JDK/CGLIB 动态代理

1、代理模式

简单来说就是我们使用代理对象代替对真实对象的访问,在不改变真实对象的前提下,提供额外的功能操作,增强目标对象的功能。
代理模式可分为静态代理和动态代理两种方式

2、静态代理

2.1 描述

静态代理需要手写代理实现类去实现接口,并去重写接口中的每个方法。
非常不灵活且麻烦,因为需要对每一个目标对象创建一个实现类;而且一旦接口中新增一个方法,目标对象和实现类都需要进行相应的调整。
从 JVM 层面来说,静态代理在编译期就已经将接口、实现类、代理类编译成 .class 文件了。

2.2 实现步骤

  • 定义一个接口和实现类;
  • 创建一个代理实现类同样实现这个接口;
  • 将目标对象注入到代理类,然后在代理类的对应方法调用目标对象的相应方法

2.3 场景实践

现在设计一个发送短信的场景,对发送短信接口作增强,手写一个发短信增强的静态代理类

2.3.1 定义发送短信接口

public interface SmsService {

    String send(String message);
}

2.3.2 定义发送短信接口实现类

public class SmsServiceImpl implements SmsService {

    @Override
    public String send(String message) {
        System.out.println("发送短信内容:" + message);
        return message;
    }
}

2.3.3 创建代理类并实现同样的接口

public class SmsProxy implements SmsService {

    private final SmsService smsService;

    public SmsProxy(SmsService smsService) {
        this.smsService = smsService;
    }

    @Override
    public String send(String message) {
        System.out.println("发送短信之前,可添加操作");
        smsService.send(message);
        System.out.println("发送短信之后,可添加操作");
        return message;
    }
}

2.3.4 代码测试

public class ProxyTest {

    public static void main(String[] args) {
        // 1、静态代理
		staticProxy();
    }

    /**
     * 静态代理测试
     */
    public static void staticProxy() {
        // 真实对象
        SmsService smsService = new SmsServiceImpl();
        // 代理对象
        SmsProxy smsProxy = new SmsProxy(smsService);
        // 使用代理对象代替对真实对象的访问,
        // 在不改变原目标对象的情况下,提供额外的功能操作,扩展目标对象的功能;
        smsProxy.send("静态代理--发短信给小马");
    }
}

方法运行后输出内容:

发送短信之前,可添加操作
发送短信内容:静态代理--发短信给小马
发送短信之后,可添加操作

从输出结果可以清晰的看到,在执行发送短信业务前后分别执行了我们设计的增强功能。

3、动态代理

与静态代理相比,动态代理更加灵活。我们不需要针对每一个目标对象都单独创建一个代理类,并且也不必须要实现接口,可以直接代理类。
JVM 层面来说,动态代理是在运行时期动态生成类字节码并加载到 JVM 中去。
动态代理的实现方式有很多种,最主要的还是 JDK 动态代理CGLIB 动态代理

3.1 JDK 动态代理

举报

相关推荐

0 条评论