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