spring aop之链式调用的实现
概述
aop
(aspect orient programming
),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等。 spring
aop
采用的是动态代理,在运行期间对业务方法进行增强,所以不会生成新类,spring
aop
提供了对jdk
动态代理的支持以及cglib的支持。本章我们不关注aop
代理类的实现,我简单实现一个指定次序的链式调用。
实现链式调用的
methodinterceptor
定义拦截器链,methodinvocation
递归进入下一个拦截器链中。类图如下:
methodinterceptor
public interface methodinterceptor { object invoke(methodinvocation invocation) throws throwable; }
methodinvocation
public interface methodinvocation { object proceed() throws throwable; }
abstractaspectjadvice
抽象类,实现methodinterceptor
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
前置通知
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
后置通知
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()
方法递归实现链式调用。
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
类
public class niocoderservice { public void testaop() { system.out.println("http://niocoder.com/"); } }
transactionmanager
模拟通知类
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
测试类,测试通知
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
的顺序
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:
代码下载
github:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
详解Spring框架之基于Restful风格实现的SpringMVC
-
使用Spring的注解方式实现AOP实例
-
关于spring中aop的注解实现方法实例详解
-
Spring实现AOP的4种方式 博客分类: spring spring代理的AOP@AspectJ注解POJOAspectJ
-
基于spring的aop实现多数据源动态切换 博客分类: javaspring 动态切换springaopAbstractRoutingDataSource
-
Spring AOP 常用的四种实现方式 博客分类: 框架开发 springaop
-
Spring AOP中定义切点的实现方法示例
-
spring5 源码深度解析----- Spring事务 是怎么通过AOP实现的?(100%理解Spring事务)
-
java之反射调用某个接口的所有实现类
-
Spring AOP的实现及源码解析