博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
探析Spring AOP(二):Spring AOP的实现机制
阅读量:6906 次
发布时间:2019-06-27

本文共 2154 字,大约阅读时间需要 7 分钟。

Spring AOP 属于第二代 AOP, 采用动态代理机制和字节码生成技术实现 。

  与最初的 AspectJ 采用编译器将横切逻辑织入目标对象不同,动态代理机制和字节码生成都是在运行期间为目标对象生成一个代理对象,而将横切逻辑织入到这个代理对象中,系统最终使用的是织入了横切逻辑的代理对象,而不是真正的目标对象。
一、动态代理

  我们可以为指定的接口在系统运行期间动态的生成代理对象, 从而帮助我们走出最初使用静态代理实现 AOP 的窘境

  动态代理机制的实现主要由 java.lang.reflect.Proxy 类和java.lang.reflect.InvocationHandler接口。
  详细使用请看:Java设计模式之—静态代理和动态代理
  
  动态代理的缺点:动态代理只能对实现了相应Interface的类使用,如果某个类没有实现任何的Interface,就无法使用动态代理对其产生相应的代理对象!
  因此:在默认情况下,如果Spring AOP发现目标实现了相应的Interface,则采用动态代理为其生成代理对象实例;而如果目标对象没有实现任何的Interface,Spring AOP会尝试使用CGLIB动态字节码生成类库,为目标对象生成代理对象实例!

二、CGLIB动态字节码生成

  使用CGLIB扩展对象行为的原理是:对目标对象进行继承扩展,为其生成相应的子类,而子类可以通过覆写来扩展父类的行为,只要将横切逻辑的实现放到子类中,然后让系统使用扩展后的目标对象的子类,就可以达到与代理模式相同的效果了。

  记住:相比于动态代理,CGLIB的优势就是,可以为没有实现任何接口的类进行扩展

  例如:

  目标类如下:(这里不实现任何接口)

public class Requestable {

public void request() {      System.out.println("requestable without implementint any interface");  }

}

  要对该类进行继承扩展,所以我们要使用CGLIB类库,实现一个net.sf.cglib.proxy.Callback,或者使用net.sf.cglib.proxy.MethodInterceptor(继承自Callback)

import java.lang.reflect.Method;

import org.joda.time.TimeOfDay;

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

public class RequestCallback implements MethodInterceptor {

public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {      if(method.getName().equals("request")) {          System.out.println("你调用了request方法")        return proxy.invokeSuper(object, args);      }      return null;  }

}

  到了这里,我们使用MethodInterceptor为request方法实现了对request请求进行控制的逻辑

  然后我们现在通过Enhancer为目标对象动态生成一个子类,将RequestCallback的横切逻辑附加到该子类中:

import net.sf.cglib.proxy.Enhancer;

public class Client {

public static void main(String[] args) {      Enhancer enhancer = new Enhancer();      //设置父类    enhancer.setSuperclass(Requestable.class);      //设置Callback    enhancer.setCallback(new RequestCallback());      Requestable proxy = (Requestable) enhancer.create();      proxy.request();  }

}

  结果如下:

  你调用了request方法
  requestable without implementint any interface

  缺点:使用 CGLIB 对类进行扩展的唯一限制就是 无法对 final 方法进行覆写

三、总结

  以上两种技术(动态代理 与 动态字节码生成) 就是 Spring AOP 所使用的核心技术,也就是 Spring AOP 的Weaving And Weaver 的实现原理了

转载地址:http://oumdl.baihongyu.com/

你可能感兴趣的文章
IntelliJ IDEA优秀插件(编程通用)
查看>>
API返回错误信息的最佳实践
查看>>
AngularJS实现三级Table列表
查看>>
scala sortBy and sortWith
查看>>
请求合并哪家强
查看>>
nodejs检查已安装模块
查看>>
solr联合多个字段进行检索(multivalued和copyfield的使用)
查看>>
准备PPT过程中的一些文档记录
查看>>
Catel(翻译)-为什么选择Catel
查看>>
SQL Server 数据库备份和还原
查看>>
微信小程序 - 贝塞尔曲线(购物车效果)
查看>>
C#在64位操作系统上连接Oracle的问题和解决方案
查看>>
使用 IntraWeb (11) - 基本控件之 TIWButton
查看>>
Python数据结构——散列表
查看>>
javaScript之function定义
查看>>
PowerShell常用的.Net 、COM对象(New-Object、Assembly)、加载程序集
查看>>
JAVASCRIPT+DHTML实现表格拖动
查看>>
C++ 内存对齐
查看>>
责任链模式
查看>>
Android 仿携程活动列表边框布局
查看>>