知微坚果的拾光小镇 知微坚果的拾光小镇
首页
随笔
  • Golang

    • 基础
    • 第三方库
  • 前端

    • Vue
    • Flutter
  • 开发工具
  • 系统工具
  • Timer (opens new window)
  • 时间线
  • 关于
GitHub (opens new window)

知微坚果

行者常至,为者常成
首页
随笔
  • Golang

    • 基础
    • 第三方库
  • 前端

    • Vue
    • Flutter
  • 开发工具
  • 系统工具
  • Timer (opens new window)
  • 时间线
  • 关于
GitHub (opens new window)
  • Java动态代理基础

  • 后端
  • Java
知微坚果
2020-12-10
目录

Java动态代理基础

# 代理模式

为其他对象提供一个代理以控制对某个对象的访问。代理类主要负责为委托了(真实对象)预处理消息、过滤消息、传递消息给委托类,代理类不现实具体服务,而是利用委托类来完成服务,并将执行结果封装处理。

其实就是代理类为被代理类预处理消息、过滤消息并在此之后将消息转发给被代理类,之后还能进行消息的后置处理。代理类和被代理类通常会存在关联关系(即上面提到的持有的被带离对象的引用),代理类本身不实现服务,而是通过调用被代理类中的方法来提供服务。

代理模式是设计模式中非常重要的一种类型,而设计模式又是编程中非常重要的知识点,特别是在业务系统的重构中,更是有举足轻重的地位。代理模式从类型上来说,可以分为 静态代理和动态代理两种类型。

# 使用

首先看一下静态代理的实现:

//做蛋糕的机器
public interface CakeMachine{
    void makeCake();
}

//专门做水果蛋糕的机器
class FruitCakeMachine implements CakeMachine{
    public void makeCake() {
        System.out.println("Making a fruit cake...");
    }
}

// 静态代理 杏仁蛋糕代理
public class ApricotCakeProxy implements CakeMachine{
    private CakeMachine cakeMachine;
    public ApricotCakeProxy(CakeMachine cakeMachine) {
        this.cakeMachine = cakeMachine;
    }
    public void makeCake() {
        cakeMachine.makeCake();
        System.out.println("adding apricot...");
    }
}

//蛋糕店
public class CakeShop {
    public static void main(String[] args) {
          //可以给各种各样的蛋糕加上杏仁
          FruitCakeMachine fruitCakeMachine = new FruitCakeMachine();
        ApricotCakeProxy apricotProxy = new ApricotCakeProxy(fruitCakeMachine);
        apricotProxy.makeCake();
        apricotProxy = new ApricotCakeProxy(new ChocolateCakeMachine());
        apricotProxy.makeCake();
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

下面看一下如何用Java动态代理实现:

// Java动态代理
public class ApricotHandler implements InvocationHandler {
    private Object object;
    public ApricotHandler(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(object, args);
        System.out.println("添加杏仁");
        return result;
    }
}
public class CakeShop {
    public static void main(String[] args) {
        //动态代理(可以同时给蛋糕、面包等加杏仁)
        //给蛋糕加上杏仁
        FruitCakeMachine fruitCakeMachine = new FruitCakeMachine();
        ApricotHandler apricotHandler = new ApricotHandler(fruitCakeMachine);
        CakeMachine cakeMachine = (CakeMachine) Proxy.newProxyInstance(fruitCakeMachine.getClass().getClassLoader(),
                fruitCakeMachine.getClass().getInterfaces(),
                apricotHandler);
        cakeMachine.makeCake();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

而 Java 动态代理只是动态代理的一种实现方式而已,动态代理还有另外一种实现方式,即 CGLib(Code Generation Library)。 通过CGLib实现:

public class ApricotInterceptor implements MethodInterceptor {
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        methodProxy.invokeSuper(o, objects);
        System.out.println("adding apricot...");
        return o;
    }
}

public class CakeShop {
    public static void main(String[] args) { 
        //CGLib动态代理(可以同时给蛋糕、面包等加杏仁)
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(FruitCakeMachine.class);
        enhancer.setCallback(new ApricotInterceptor());
        FruitCakeMachine fruitCakeMachine = (FruitCakeMachine) enhancer.create();
        fruitCakeMachine.makeCake();
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 基本原理

# Java动态代理

动态代理的具体步骤:

  1. 通过实现 InvocationHandler 接口创建自己的调用处理器;
  2. 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
  3. 通过 反射机制 获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
  4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

Java动态代理流程图 20201210154446

# 参考文献

Java动态代理 深度详解 (opens new window)

JAVA动态代理 (opens new window)

#Java#设计模式
更新时间: 12/2/2022, 12:38:29 AM
最近更新
01
SpringBoot3.0快速上手
12-07
02
Spring事务管理源码分析
12-06
03
Golang工程结构最佳实践
12-04
更多文章>
Theme by Vdoing | Copyright © 2022-2022 知微坚果 | 拾光小镇
蜀ICP备17001150号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式