内容简介:关关雎鸠,在河之洲。窈窕淑女,君子好逑。
关关雎鸠,在河之洲。窈窕淑女,君子好逑。
概述
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: https://github.com/longfeizheng/data-structure-java/blob/master/src/main/java/cn/merryyou/aop
代码下载
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 直观讲解-RPC调用和HTTP调用的区别
- 调用链系列一:解读UAVStack中的调用链技术
- 调用链系列二:解读UAVStack中的调用链技术
- 调用链系列三:解读UAVStack中的调用链技术
- dubbo源码解析(二十七)远程调用——injvm本地调用
- 微服务间的调用和应用内调用有什么区别
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
你必须知道的495个C语言问题
Steve Summit / 孙云、朱群英 / 人民邮电出版社 / 2009-2 / 45.00元
“本书是Summit以及C FAQ在线列表的许多参与者多年心血的结晶,是C语言界最为珍贵的财富之一。我向所有C语言程序员推荐本书。” ——Francis Glassborow,著名C/C++专家,ACCU(C/C++用户协会)前主席 “本书清晰阐明了Kernighan与Ritchie《The C programming Language》一书中许多简略的地方,而且精彩地总结了C语言编程......一起来看看 《你必须知道的495个C语言问题》 这本书的介绍吧!