概述
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之链式调用的实现的详细内容...