概述
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