Spring AOP之 java 动态代理(Proxy 与 InvocationHandler)理解

本文介绍了面向切面编程(AOP)的概念及其在Java中的应用。通过实例演示了如何使用Proxy和InvocationHandler实现动态代理,为现有方法添加额外功能而无需修改原始代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学习spring的过程中,了解到一个很重要的java编程思想,就是面向切面的编程(aop)。什么是面向切面的编程呢?对于这个概念我在网上查了,得到如下的答案:

AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。它是一种新的方法论,它是对传统OOP编程的一种补充。

概念性的东西比较死,关键是要理解其中的原理。看下图所示:

这里写图片描述

当你有一个写好的方法,想要在其调用的前面或者后面加上一些记录日志或别的一些逻辑,但又不想更改(或者不能改)原有的代码时,AOP就能发挥它极大的优势了。接下来看看使用Proxy和 InvocationHandler是如何实现的。

public interface UserDao {//定义一个保存User对象到数据库的接口 

    public void save(User user) ;

}
public class UserDaoImpl implements UserDao {//接口的实现 


    @Override

    public void save(User user) {

        System.out.println("user saved!");

    }

}
import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

//编写切面逻辑类,必须要实现InvocationHandler 接口

public class DebugInterceptor implements InvocationHandler {

    private Object target;

    public Object getTarget() {

        return target;

    }

    public void setTarget(Object target) {

        this.target = target;

    }



    //需要插入的逻辑

    private void before(Method m) {

        System.out.println(m.getName() + " start!");

    }

    @Override

    public Object invoke(Object proxy, Method method, Object[] args)

            throws Throwable {

        before(method);

        method.invoke(target, args);//使用java反射调用代理方法

        return null;

    }

} 

使用Junit4写了个单元测试,测试代理方法。调用Proxy类的静态方法newProxyInstance(classloader,interfaces,handler)产生代理对象。代理对象与被代理对象实现了同一个接口UserDao,所以能调用其中的save方法。

public class ProxyTest {

    @Test

    public void testProxy() {

        UserDao userDao = new UserDaoImpl();

        DebugInterceptor di = new DebugInterceptor();

        di.setTarget(userDao);

        UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),

                userDao.getClass().getInterfaces(), di);

        userDaoProxy.save(new User());

    }

} 

测试结果

save start!
user saved!

成功将切面逻辑加入到方法调用之前,嘿嘿。

到此,Proxy与InvocationHandler实现动态代理的实现过程就搞定了。java动态代理不只有这一个方法,还能用CGlib,CGlib是一个强大的,高性能,高质量的代码生成类库,这里就不多做介绍了,大家可以到网上自己查。

还有spring的AOP实现的动态代理不只是这样子,它使用aspectJ这个切面框架。具体的等以后再继续说吧。继续研究。。。

最后,发现自己写得好少,也存在很多不足,欢迎大家指点与吐槽。

在交流中成长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值