不使用Spring AOP的情况下,如何实现AOP功能?

Spring AOP基于动态代理实现。

一、代理模式

代理模式是非常常用的一种设计模式,在我们的应用中经常被使用。一般场景是,我们有一个现成的类,它的功能比较的完善了,但是还是存在某些欠缺,这个时候我们需要去扩展一些新的功能,但又不想去重造轮子,这个时候可以使用代理类来替代原来的目标类,通过组合的模式,增加一种为目标类增加一些额外的功能。

1、代理模式类结构图

代理模式的类结构图一般如下:

不使用Spring AOP的情况下,如何实现AOP功能?插图

2、代理模式序列图

不使用Spring AOP的情况下,如何实现AOP功能?插图2

二、Spring AOP代理内部实现原理

1、实现原理

Spring AOP默认的AOP代理使用标准JDK动态代理。它允许代理任何接口(或接口集)。

Spring AOP还可以使用CGLIB代理。主要针对对于代理类而不是接口。默认情况下,如果业务对象没有实现接口,则使用CGLIB。由于对接口而不是类进行编程是一种良好的实践,所以业务类通常实现一个或多个业务接口。在那些(希望很少)情况下,强制使用CGLIB是可能的,您需要建议一个没有在接口上声明的方法,或者需要将经过代理的对象作为具体类型传递给方法。理解Spring AOP是基于代理的这一事实是很重要的。请参阅理解AOP代理,以全面检查这个实现细节的实际含义。

2、具体实现

不使用Spring AOP的情况下,如何实现AOP功能?插图4

Spring AOP的实现只要使用jdk的动态代理和cglib的代理,jdk动态代理针对接口,cglib针对类。

DefaultAopProxyFactory创建aop代理时决定是使用jdk动态代理还是cglib代理。

不使用Spring AOP的情况下,如何实现AOP功能?插图6

三、利用JDK动态代理实现AOP

由于对接口而不是类进行编程是一种良好的实践,所以业务类通常实现一个或多个业务接口。所以想实现AOP可以利用jdk的动态代理。

1、JDK的动态代理的两个主类

JDK的动态代理有两个主类:

  • java.lang.reflect.Proxy:创建代理实例
  • java.lang.reflect.InvocationHandler:增强的业务逻辑写在里面

2、时序图

其时序图如下所示:

不使用Spring AOP的情况下,如何实现AOP功能?插图8

四、总结

我们进一步打开JdkDynamicAopProxy的源码,发现它实现InvocationHandler接口,有兴趣的话可以参考invoke实现,和上面jdk的动态代理时序一致。

发表评论