spring aop之链式调用的实现

时间:2022-11-02 16:59:55

概述

aopaspect orient programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等。 spring aop采用的是动态代理,在运行期间对业务方法进行增强,所以不会生成新类,spring aop提供了对jdk动态代理的支持以及cglib的支持。本章我们不关注aop代理类的实现,我简单实现一个指定次序的链式调用

实现链式调用的

methodinterceptor定义拦截器链,methodinvocation 递归进入下一个拦截器链中。类图如下:

spring aop之链式调用的实现

methodinterceptor

?
1
2
3
4
public interface methodinterceptor {
 
  object invoke(methodinvocation invocation) throws throwable;
}

methodinvocation

?
1
2
3
4
public interface methodinvocation {
 
  object proceed() throws throwable;
}

abstractaspectjadvice

抽象类,实现methodinterceptor

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public abstract class abstractaspectjadvice implements methodinterceptor{
 
  private method advicemethod;
 
  private object adviceobject;
 
  public abstractaspectjadvice(method advicemethod, object adviceobject) {
    this.advicemethod = advicemethod;
    this.adviceobject = adviceobject;
  }
 
  public method getadvicemethod() {
    return this.advicemethod;
  }
 
  public void invokeadvicemethod() throws throwable {
    advicemethod.invoke(adviceobject);
  }
}

aspectjbeforeadvice

前置通知

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class aspectjbeforeadvice extends abstractaspectjadvice {
 
  public aspectjbeforeadvice(method method, object adviceobject) {
    super(method, adviceobject);
  }
 
  @override
  public object invoke(methodinvocation invocation) throws throwable{
    this.invokeadvicemethod();
    object o = invocation.proceed();
    return o;
  }
}

aspectjafterreturningadvice

后置通知

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class aspectjafterreturningadvice extends abstractaspectjadvice {
 
  public aspectjafterreturningadvice(method method, object adviceobject) {
    super(method, adviceobject);
  }
 
  @override
  public object invoke(methodinvocation invocation) throws throwable{
    object o = invocation.proceed();
    this.invokeadvicemethod();
    return o;
  }
}

reflectivemethodinvocation

实现methodinvocationproceed()方法递归实现链式调用。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class reflectivemethodinvocation implements methodinvocation {
 
  private final object targetobject;
 
  private final method targetmethod;
 
  private final list<methodinterceptor> interceptorlist;
 
  private int currentinterceptorindex = -1;
 
  public reflectivemethodinvocation(object targetobject, method targetmethod, list<methodinterceptor> interceptorlist) {
    this.targetobject = targetobject;
    this.targetmethod = targetmethod;
    this.interceptorlist = interceptorlist;
  }
 
  @override
  public object proceed() throws throwable {
 
    if (this.currentinterceptorindex == this.interceptorlist.size() - 1) {
      return invokejoinpoint();
    }
 
    this.currentinterceptorindex++;
 
    methodinterceptor interceptor =
        this.interceptorlist.get(this.currentinterceptorindex);
    return interceptor.invoke(this);
  }
 
  private object invokejoinpoint() throws throwable {
 
    return this.targetmethod.invoke(this.targetobject);
  }
}

niocoderservice

模拟service

?
1
2
3
4
5
6
public class niocoderservice {
 
  public void testaop() {
    system.out.println("http://niocoder.com/");
  }
}

transactionmanager

模拟通知类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class transactionmanager {
  public void start() {
    system.out.println("start tx");
  }
 
  public void commit() {
    system.out.println("commit tx");
  }
 
  public void rollback() {
    system.out.println("rollback tx");
  }
 
}

reflectivemethodinvocationtest

beforeadvice->afterreturningadvice

测试类,测试通知

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class reflectivemethodinvocationtest {
 
  private aspectjbeforeadvice beforeadvice = null;
 
  private aspectjafterreturningadvice afterreturningadvice = null;
 
  private niocoderservice niocoderservice;
 
  private transactionmanager tx;
 
  public void setup() throws exception {
    niocoderservice = new niocoderservice();
    tx = new transactionmanager();
    beforeadvice = new aspectjbeforeadvice(transactionmanager.class.getmethod("start"), tx);
    afterreturningadvice = new aspectjafterreturningadvice(transactionmanager.class.getmethod("commit"), tx);
  }
 
  public void testmethodinvocation() throws throwable {
    method method = niocoderservice.class.getmethod("testaop");
    list<methodinterceptor> interceptorlist = new arraylist<>();
    interceptorlist.add(beforeadvice);
    interceptorlist.add(afterreturningadvice);   
 
    reflectivemethodinvocation mi = new reflectivemethodinvocation(niocoderservice, method, interceptorlist);
 
    mi.proceed();
  }
 
 
  public static void main(string[] args) throws throwable {
    reflectivemethodinvocationtest reflectivemethodinvocationtest = new reflectivemethodinvocationtest();
    reflectivemethodinvocationtest.setup();
    reflectivemethodinvocationtest.testmethodinvocation();
  }
}

输出:

start tx
http://niocoder.com/
commit tx

时序图 beforeadvice->afterreturningadvice

spring aop之链式调用的实现

spring aop之链式调用的实现

afterreturningadvice->beforeadvice

修改interceptorlist的顺序

?
1
2
3
4
5
6
7
8
9
10
public void testmethodinvocation() throws throwable {
    method method = niocoderservice.class.getmethod("testaop");
    list<methodinterceptor> interceptorlist = new arraylist<>();
    interceptorlist.add(afterreturningadvice);
     interceptorlist.add(beforeadvice);
 
    reflectivemethodinvocation mi = new reflectivemethodinvocation(niocoderservice, method, interceptorlist);
 
    mi.proceed();
  }

输出:

start tx
http://niocoder.com/
commit tx

时序图 afterreturningadvice->beforeadvice

spring aop之链式调用的实现

spring aop之链式调用的实现

代码下载

github:https://github.com/longfeizheng/data-structure-java/blob/master/src/main/java/cn/merryyou/aop

代码下载

github:https://github.com/longfeizheng/data-structure-java

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://segmentfault.com/a/1190000018206756