概述
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.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
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
代码下载
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