SpringAOP和动态代理技术

一直拖拖拖,结果面试被搞了,下定决心一天搞定

AOP将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),切面将那些与业务无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

自己的话来说,就是将一些与业务核心逻辑无关并且多个对象公用的代码块封装起来,然后供切入到代码中, 供它们使用

 

那么aop是如何实现的。一种是基于动态代理,我们看看动态代理的解释

动态创建一组指定的接口的实现对象(在运行时,创建实现了指定的一组接口的对象)

注意这里是接口并不是实现类,那么具体如何实现的?

主要分为两个部分:

第一个是创建动态代理类的类

然后我们就先来看一下动态代理的代码:

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)

这个方法用来创建代理实体类。

上面这个就是动态代理类(Proxy)类中的创建代理对象的方法,下面介绍一下方法的三个参数:

 

  • ClassLoader loader:就是用来加载代理类的类加载器
  • Class<?>[] interfaces:因为代理类也需要和委托类实现相同的接口,所以传入需要实现的接口
  • InvocationHandler h:调用处理器,为了实现扩展,我们将扩展的这一层分离出来就是这个处理器,那么代理类调用的所有方法都会到这里经过处理再去执行。

 

第二个是InvocationHandler。

我们要知道,代理类执行的所有方法都是要交给这个处理器执行,而这个处理器通过下面这个invoke方法执行

我们从它的方法的参数看:

 

我们知道handler这个执行器是作为参数传入了代理类中,因此我们可以获取它的所有信息,

我们能通过这三个参数

Object proxy:这是代理实例,我们通过有代理实例,才能知道他正在执行的方法等信息,然后调用

Method method:这个参数得知我们此刻在代理实例上调用的方法

Object[] args:知道调用方法的参数,才能接着调用

我们知道了代理类的所有方法都会传入handler执行,因此我们在invoke里添加了想要添加的方法然后添加委托类的方法就能扩展功能了,这就是aop的功能

如何在invoke中调用我们委托了的方法,我们可以通过构造方法持有委托类对象,在invoke方法中调用委托类的方法

 

这里我在学习的时候发现个有趣的事,就是proxy这个对象

Student是我的委托类,而Person是接口,我对invoke方法打断点后发现了有趣的问题:

这是运行时参数数据,第一个proxy竟然是以委托类为模板创建的,但注意,这个类是以委托类为模板创建的一个对象和handler持有的委托类对象不是一个,因此我猜想:动态代理既然无法直接创建一个实现接口的类,我们就创建一个和委托对象相同的类的对象,在里面动态的织入方法。 

总结:使用动态代理的方法实现aop的步骤是,我们必须有一个接口,我们可以新建一个创造代理的类的类newProxyInstance,这个类中接受要被代理对象实现的接口,并且接受类加载器和一个执行器 InvocationHandler,通过这个执行器我们能接受那个实现接口的对象,在这个类里可以重写一个invoke方法,这个方法里既能调用被代理对象的方法,还能使用 自己添加的类的方法,最后返回值就是代理对象的返回值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值