摘要:本文次要讲了Spring Aop动静代理实现的两种形式。

1. Spring AOP

Spring是一个轻型容器,Spring整个系列的最最外围的概念当属IoC、AOP。可见AOP是Spring框架中的外围之一,在利用中具备十分重要的作用,也是Spring其余组件的根底。AOP(Aspect Oriented Programming),即面向切面编程,能够说是OOP(Object Oriented Programming,面向对象编程)的补充和欠缺。OOP引入封装、继承、多态等概念来建设一种对象层次结构,用于模仿公共行为的一个汇合。不过OOP容许开发者定义纵向的关系,但并不适宜定义横向的关系,例如日志性能。

对于AOP的基础知识,并不是本文的重点,咱们次要来看下AOP的外围性能的底层实现机制:动静代理的实现原理。AOP的拦挡性能是由java中的动静代理来实现的。在指标类的根底上减少切面逻辑,生成加强的指标类(该切面逻辑或者在指标类函数执行之前,或者指标类函数执行之后,或者在指标类函数抛出异样时候执行。不同的切入机会对应不同的Interceptor的品种,如BeforeAdviseInterceptor,AfterAdviseInterceptor以及ThrowsAdviseInterceptor等)。

那么动静代理是如何实现将切面逻辑(advise)织入到指标类办法中去的呢?上面咱们就来具体介绍并实现AOP中用到的两种动静代理。

AOP的源码中用到了两种动静代理来实现拦挡切入性能:jdk动静代理和cglib动静代理。两种办法同时存在,各有优劣。jdk动静代理是由java外部的反射机制来实现的,cglib动静代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比拟高效,而asm在生成类之后的相干执行过程中比拟高效(能够通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。

上面咱们别离来示例实现这两种办法。

2. JDK动静代理

2.1 定义接口与实现类

下面代码定义了一个被拦挡对象接口,即横切关注点。上面代码实现被拦挡对象接口。

2.2 JDK动静代理类

上述代码实现了动静代理类JDKProxy,实现InvocationHandler接口,并且实现接口中的invoke办法。当客户端调用代理对象的业务办法时,代理对象执行invoke办法,invoke办法把调用委派给targetObject,相当于调用指标对象的办法,在invoke办法委派前判断权限,实现办法的拦挡。

2.3 测试

后果如下:

3. CGLIB字节码生成

3.1 要代理的类

CGLIB既能够对接口的类生成代理,也能够针对类生成代理。示例中,实现对类的代理。

该类的实现和下面的接口实现一样,为了放弃对立。

3.2 CGLIB动静代理类

上述实现了创立子类的办法与代理的办法。getProxy(SuperClass.class)办法通过入参即父类的字节码,扩大父类的class来创立代理对象。intercept()办法拦挡所有指标类办法的调用,obj示意指标类的实例,method为指标类办法的反射对象,args为办法的动静入参,methodProxy为代理类实例。method.invoke(targetObject, args)通过代理类调用父类中的办法。

3.3 测试

后果如下:

4. 总结

本文次要讲了Spring Aop动静代理实现的两种形式,并别离介绍了其优缺点。jdk动静代理的利用前提是指标类基于对立的接口。如果没有该前提,jdk动静代理不能利用。由此能够看出,jdk动静代理有肯定的局限性,cglib这种第三方类库实现的动静代理利用更加宽泛,且在效率上更有劣势。

JDK动静代理机制是委托机制,不须要以来第三方的库,只有要JDK环境就能够进行代理,动静实现接口类,在动静生成的实现类外面委托为hanlder去调用原始实现类办法;CGLib 必须依赖于CGLib的类库,应用的是继承机制,是被代理类和代理类继承的关系,所以代理类是能够赋值给被代理类的,如果被代理类有接口,那么代理类也能够赋值给接口。

参考

  1. jdk动静代理代理与cglib代理原理探索
  2. AOP的底层实现-CGLIB动静代理和JDK动静代理

本文分享自华为云社区《还不懂Spring AOP?一文带你搞懂动静代理》,原文作者:aoho 。

点击关注,第一工夫理解华为云陈腐技术~