Spring AOP的实现机制(一)----- 动态代理

布满荆棘的人生 2022-08-14 00:59 250阅读 0赞
  1. <span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>Spring AOP的实现机制
  2. 动态代理
  3. (1)静态代理
  4. 举例说明如下:
  5. ISubject 该接口是对被访问者或被访问资源的抽象。
  6. SubjectImpl 被访问者或者被访问资源的具体实现,如果你要访问某位明星,SubjectImpl就是你想访问的明星
  7. SubjectProxy 被访问者或者被访问资源的代理实现类,该类持有一个ISubject接口的具体实例。在这个场景中,我们要对SubjectImpl进行代理,那么SubjectProxy现在
  8. 持有的就是SubjectImpl的实例。
  9. public class SubjectProxy implements ISubject{
  10. private ISubject subject;
  11. public String request(){
  12. //add pre-process logic if necessary
  13. String originalResult=subject.request();
  14. //add post process logic if necessary
  15. return "proxy:" +originalResult
  16. }
  17. public ISubject getSubject(){
  18. return subject;
  19. }
  20. public void setSubject(ISubject subject){
  21. this.subject=subject;
  22. }
  23. }
  24. public class SubjectImpl implements ISubject{
  25. public String request(){
  26. //process logic
  27. return "OK";
  28. }
  29. }
  30. 这里SubjectImpl和SubjectProxy都实现了相同的接口ISubject ,SubjectProxy内部持有SubjectImpl的引用。
  31. 在将请求转发给被代理对象SubjectImpl之前或者之后,都可以根据情况插入其他处理逻辑。如果SubjectImpl
  32. 是系统中的Joinpoint所在的对象,即目标对象,那么就可以为这个目标对象创建一个代理对象,然后将横切
  33. 逻辑添加到这个代理对象中。当系统使用这个代理对象运行的时候,原有逻辑的实现和横切逻辑就完全融合到
  34. 一个系统中。
  35. 然后将代理对象绑定到系统中的实现代码如下:
  36. ISubject target=new ISubjectImpl();
  37. ISubject fianlSubject =new SubjectProxy(target);
  38. fianlSubject.request();
  39. 上面属于静态代理,对于多个具有resquest方法的类,我们要为其织入相同的逻辑时又得重新实现一个代理对象,
  40. 所以说静态代理原理上是可行的,但是存在其他问题。
  41. (2)动态代理
  42. 使用动态代理机制,可以为指定的接口在系统运行期间动态生成代理对象。
  43. 动态代理机制的实现主要由一个类和一个接口组成,即java.lang.reflect.Proxy和java.lanf.reflect.InvocationHandler接口
  44. 虽然要为ISubject和IRequestable两种类型提供代理对象,但因为代理对象中药添加的横切逻辑时一样的,所以我们
  45. 只需要实现一个InvocationHandler就可以了。
  46. 简单的实现代码如下:
  47. public class RequestableInvocationHandler implements InvocationHandler{
  48. private Object target;
  49. public RequestableInvocationHandler(Object target){
  50. this.target=target;
  51. }
  52. public Object invoke(Object proxy,Method method,Object[]args)throws Throwable{
  53. if(method.getName().equals("request"))
  54. {
  55. //aspect
  56. }
  57. return method.invoke(target,args);
  58. }
  59. return null;
  60. }
  61. 然后我们就可以使用Proxy类,根据RequestableInvocationHandler的逻辑,为ISubject和IRequestable两种类型生成相应的代理对象实例
  62. ISubject subject=(ISubject)Proxy.newProxyInstance(Subject.class.getClassLoader(),new Class[]{ISubject.class},new RequestableInvocationHandler(new SubjectImpl()));
  63. subject.request();
  64. IRequestable requestable=(IRequestable)Proxy.newProxyInstance(IRequestable.class.getClassLoader(),new Class[]{IRequestable.class},new RequestableInvocationHandler(new RequestableImpl()));
  65. requestable.request();
  66. InvocationHandler就是我们实现横切逻辑的地方,它是横切逻辑的载体,作用和Advice一样。所以在使用动态代理机制实现AOP的过程
  67. 中,我们可以在InvocationHandler的基础上细化程序结构,并根据Advice的类型,分化出对应不同Advice类型的程序结构。
  68. 动态代理虽好,但是不能满足所有需求。因为动态代理机制只能对实现了相应Interface的类使用,如果某个类没有实现任何的Interface
  69. 就无法使用动态代理为其生成相应的动态代理对象
  70. 默认情况下,如果Spring AOP发现目标对象实现了相应Interface,则采用动态代理机制为其生成代理对象实例。而如果目标对象没有实现任何Interface,Spring AOP 会尝试使用CGLIB
  71. (Code Genaration Library)的开源的动态字节码生成类库,为目标对象动态生成代理对象
  72. 定义目标类如下:
  73. pubic class Requestable{
  74. public void request(){
  75. System.out.println("rq in Requestable without implement any interface");
  76. }
  77. }
  78. 要对Requestable类进行扩展,首先需要实现一个net.sf.cglib.proxy.Callback。不过更多的时候我们直接使用net.sf.cglib.proxy.MethodInterceptor接口
  79. public class RequestCtrlCallback implements MethodInterceptor{
  80. public Object intercept(Object object,Method method,Object[]args,MethodProxy proxy)throws Throwable{
  81. if(method.getName.equals("request")){
  82. //process logic;
  83. return proxy.invokeSuper(object,args);
  84. }
  85. }
  86. }
  87. 这样,RequestableCallback就实现了对request()方法请求进行访问控制的逻辑。现在通过CGLIB的Enhancer为目标对象动态生成一个子类,
  88. 并将RequestableCallback中的横切逻辑附加到该子类中.
  89. Enhancer enchaner=new Enhancer();
  90. enchaner.setSuperclass(Requestable.class);
  91. enchaner.setCallback(new RequestableCallback());
  92. Requestable proxy =(Requestable)enchaner.create();
  93. proxy.request();
  94. </strong></span>

发表评论

表情:
评论列表 (有 0 条评论,250人围观)

还没有评论,来说两句吧...

相关阅读

    相关 AOP动态代理机制

    通过动态代理,可以在指定位置执行对应流程。这样就可以将一些横向的功能抽离出来形成一个独立的模块,然后在指定位置插入这些功能,实现类面向切面编程,亦即AOP。 一.术语

    相关 Spring AOP&&动态代理()

    AOP :面向切面的编程 是对OOP的扩展 OOP :引入封装、继承、多态等概念来建立一种对象层次结构;OOP允许开发者定义纵向关系,而不能处理横向关系;像类似日志记录、