Java动态代理在Easy-ES/Mybatis中的实践,要想代码灵活,必须动态代理

本文介绍了JDK动态代理的概念,包括其定义、使用步骤以及在EsMapperProxy和MapperFactoryBean中的应用。讨论了动态代理的优势,如灵活性、解耦和处理横切关注点,并列举了日志记录、事务管理和权限控制等应用场景。
摘要由CSDN通过智能技术生成

1 动态代理相关

1.1 什么是动态代理?

动态代理是指在运行时创建代理对象的过程,而不是在编译时确定。JDK动态代理利用Java的反射机制,在运行时动态生成代理类和代理对象,从而实现代理功能。这意味着我们可以在运行时为任何接口创建代理对象,而无需手动编写代理类。

1.2 如何使用JDK动态代理?

使用JDK动态代理非常简单,只需遵循以下几个步骤:

  1. 定义一个接口:首先,我们需要定义一个接口,该接口将成为代理对象和被代理对象之间的契约。接口应包含代理对象和被代理对象共同的方法。
  2. 实现被代理类:创建一个实现接口的被代理类,该类将包含实际的业务逻辑。
  3. 创建InvocationHandler:实现InvocationHandler接口,并重写invoke方法。invoke方法将在代理对象的方法被调用时执行,我们可以在该方法中添加额外的逻辑。
  4. 创建代理对象:使用Proxy类的newProxyInstance方法创建代理对象。该方法接受三个参数:类加载器、接口数组和InvocationHandler对象。通过调用该方法,我们将得到一个实现了指定接口的代理对象。
  5. 使用代理对象:现在,我们可以使用代理对象来调用接口中定义的方法。代理对象会在调用方法时自动触发InvocationHandlerinvoke方法,从而允许我们在方法调用前后添加自定义的逻辑。

1.3 一个简单的案例

// 这段代码来自 Easy ES 中,可以直接 双击 shift 查到
// 而这段代码的作用就是对 Mapper 进行代理,同时可以在MapperFactoryBean(下面那个代码块)中也可以看到它的核心逻辑就是 (定义Mapper 接口 -> 创建 Mapper 代理)
public class EsMapperProxy<T> implements InvocationHandler, Serializable {

    private final Class<T> mapperInterface;

    public EsMapperProxy(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        BaseEsMapper<?> baseEsMapper = new BaseEsMapperImpl<>();
        return method.invoke(baseEsMapper, args);
    }
}

public class MapperFactoryBean<T> implements FactoryBean<T> {


    private final Class<T> mapperInterface;

    public MapperFactoryBean(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }

    @Override
    @SuppressWarnings("all")
    public T getObject() throws Exception {
        EsMapperProxy<T> esMapperProxy = new EsMapperProxy<>(mapperInterface);
        return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, esMapperProxy);
    }

    @Override
    public Class<?> getObjectType() {
        return this.mapperInterface;
    }
}

1.4 动态代理的优势和应用场景

使用JDK动态代理有以下几个优势:

  • 灵活性:动态代理允许我们在运行时为任意接口创建代理对象,无需手动编写代理类,从而提供了更大的灵活性。
  • 解耦合:代理模式可以将代理对象和被代理对象解耦,使得它们可以独立进行修改和扩展。
  • 横切关注点处理:动态代理可以用于处理横切关注点,例如日志记录、性能监控、事务管理等。我们可以通过在InvocationHandlerinvoke方法中添加相应的逻辑来实现这些功能。

JDK动态代理在以下场景中特别有用:

  • 日志记录:通过在InvocationHandler中添加日志记录逻辑,我们可以方便地记录方法的调用信息,用于调试和分析。
  • 事务管理:通过在InvocationHandler中添加事务管理逻辑,我们可以实现对方法的事务性控制,例如开启事务、提交事务、回滚事务等。
  • 权限控制:通过在InvocationHandler中添加权限验证逻辑,我们可以对方法的调用进行权限控制,以确保只有具备相应权限的用户才能执行特定操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沈自在-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值