概述
aop
(aspect orient programming
),我們一般稱為面向方面(切面)編程,作為面向?qū)ο蟮囊环N補(bǔ)充,用于處理系統(tǒng)中分布于各個(gè)模塊的橫切關(guān)注點(diǎn),比如事務(wù)管理、日志、緩存等等。 spring
aop
采用的是動(dòng)態(tài)代理,在運(yùn)行期間對(duì)業(yè)務(wù)方法進(jìn)行增強(qiáng),所以不會(huì)生成新類,spring
aop
提供了對(duì)jdk
動(dòng)態(tài)代理的支持以及cglib的支持。本章我們不關(guān)注aop
代理類的實(shí)現(xiàn),我簡(jiǎn)單實(shí)現(xiàn)一個(gè)指定次序的鏈?zhǔn)秸{(diào)用。
實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用的
methodinterceptor
定義攔截器鏈,methodinvocation
遞歸進(jìn)入下一個(gè)攔截器鏈中。類圖如下:
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
抽象類,實(shí)現(xiàn)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
實(shí)現(xiàn)methodinvocation
,proceed()
方法遞歸實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用。
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
測(cè)試類,測(cè)試通知
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
時(shí)序圖 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
時(shí)序圖 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
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://segmentfault.com/a/1190000018206756