好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

spring aop之链式调用的实现

概述

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

实现链式调用的

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

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

实现 methodinvocation , proceed() 方法递归实现链式调用。

?

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测试数据/" );

   }

}

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测试数据/
commit tx

时序图 beforeadvice->afterreturningadvice

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测试数据/
commit tx

时序图 afterreturningadvice->beforeadvice

代码下载

github: https://github测试数据/longfeizheng/data-structure-java/blob/master/src/main/java/cn/merryyou/aop

代码下载

github: https://github测试数据/longfeizheng/data-structure-java

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

原文链接:https://segmentfault测试数据/a/1190000018206756

查看更多关于spring aop之链式调用的实现的详细内容...

  阅读:10次