Java中的动态代理和AOP有什么关系?

Java中的动态代理和AOP有什么关系?


本篇将带你了解Java中的动态代理使用方法,以及动态代理和AOP到底有什么关系

动态代理

Java 中的动态代理是一种设计模式,允许在运行时动态地创建代理对象,而不需要为每个代理类写一个单独的实现,动态代理主要用于拦截方法调用,在调用目标方法之前或之后添加通用的逻辑,比如日志记录、权限校验、事务管理等

也就是说,当我们想要扩展某一个方法时,但是又不想对原本的代码进行修改,这个时候就可以为这个方法创建一个代理对象,让代理对象在调用原本方法的基础上做一些横向扩展,即不用破坏原本代码的完整性,又可以在原有基础上做更多的事情

动态代理对象
目标对象
调用
扩展业务1(前置逻辑)
执行原本方法
扩展业务2(后置逻辑)
A方法

假如我们此时有一个业务:

public class ServiceImpl implements Service{
    @Override
    public String doService() throws InterruptedException {
        System.out.println("正在执行业务...");
        Thread.sleep(10);
        return "OK";
    }
}

为了演示执行业务的效果,我将线程休眠了10毫秒,方便后续观察

此时我们希望统计该业务的耗时情况,我们可以在业务开始和结束各记录一次时间,用结束时间减去开始时间就是业务耗时:

public class ServiceImpl implements Service{
    @Override
    public String doService() throws InterruptedException {
        // 记录开始时间
        long begin = System.currentTimeMillis();
        // 执行业务
        System.out.println("正在执行业务...");
        Thread.sleep(10);
        // 记录结束时间
        long end = System.currentTimeMillis();

        System.out.println("方法执行耗时:" + (end - begin) + "毫秒");
        return "OK";
    }
}

但是通常情况下,我们并不希望更改原本的代码

此时就可以使用动态代理技术,创建一个代理对象来帮我们扩展原有功能:

创建一个ProxyUtil类,编写一个静态方法createProxy用来获取代理对象,利用JDK提供的newProxyInstance方法,传入一个InvocationHandler接口的匿名内部类对象完成动态代理生成

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

public class ProxyUtil {
    public static Service createProxy(ServiceImpl serviceImpl){
        Service proxy = (Service) Proxy.newProxyInstance(
                ProxyUtil.class.getClassLoader(),  // 参数1:指定类加载器加载代理对象字节码文件
                new Class[]{Service.class},   // 参数2:指定要代理的方法接口
                new InvocationHandler() {     // 参数3:指定代理对象要扩展的方法
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        /*
                        参数1:要生成的代理对象
                        参数2:代理的方法
                        参数3:形参列表
                         */
                        // 记录开始时间
                        long begin = System.currentTimeMillis();
                        // 执行原方法
                        Object result = method.invoke(serviceImpl);
                        // 记录结束时间
                        long end = System.currentTimeMillis();

                        System.out.println("方法执行耗时:" + (end - begin) + "毫秒");
                        return result;
                }
        });
        return proxy;
    }
}

最后我们创建一个测试类,来调用代理对象执行方法:

public class Test {
    public static void main(String[] args) throws InterruptedException {
        // 创建原对象
        ServiceImpl service = new ServiceImpl();
        
        // 创建代理对象
        Service proxy = ProxyUtil.createProxy(service);
        
        // 调用代理对象执行代理方法
        System.out.println(proxy.doService());
    }
}

AOP

聪明的你已经发现,这与我们在Spring中学习的AOP十分相似,没错,动态代理确实是AOP(面向切面编程)的核心实现方式之一,尤其是在 Java 的 Spring 框架中,动态代理被广泛用于实现 AOP 功能

对比项动态代理AOP
定义动态生成代理对象,在运行时增强目标方法。一种编程思想,解耦横切关注点与业务逻辑。
范围是技术实现手段。是概念,包含动态代理和其他实现方式。
应用场景拦截方法调用,加入通用逻辑。实现日志、事务、权限、缓存等功能。
实现方式JDK动态代理、CGLIB、Javassist等。通过动态代理、编译期或类加载期增强。
Spring支持是Spring AOP的底层实现之一。Spring AOP提供切面声明和增强注入。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值