欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

SpringAOP基础组件Advice

时间:2023-07-03
相关阅读

Spring AOP基础组件 PointcutSpring AOP基础组件 AdvisorSpring AOP基础组件 Advised 简介

表示通知的标签接口,通知的实现类可以多种,比如Interceptor;

源码

public interface Advice {}

实现子类 BeforeAdvice 简介

前置通知的标记接口;实现子类有:MethodBeforeAdvice;
Spring目前只支持方法前置通知;

AfterAdvice 简介

后置通知的标记接口,实现子类有:AfterReturningAdvice、ThrowsAdvice;

AbstractAspectJAdvice 简介

包装AspectJ切面或者AspectJ注解标注的通知方法的AOP Advice的基础类;

核心代码

public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation, Serializable { // 调用增强方法 protected Object invokeAdviceMethod( @Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex) throws Throwable { return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex)); } // 调用增强方法 protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable t) throws Throwable { return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t)); } // 根据给定参数调用增强方法 protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { Object[] actualArgs = args; if (this.aspectJAdviceMethod.getParameterCount() == 0) { actualArgs = null; } try { // 反射调用增强方法 ReflectionUtils.makeAccessible(this.aspectJAdviceMethod); return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); } catch (IllegalArgumentException ex) { throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutexpression() + "]", ex); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } }}

AspectJMethodBeforeAdvice 简介

包装AspectJ前置通知方法的Spring AOP Advice;

核心代码

public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable { @Override public void before(Method method, Object[] args, @Nullable Object target) throws Throwable { invokeAdviceMethod(getJoinPointMatch(), null, null); } @Override public boolean isBeforeAdvice() { return true; } @Override public boolean isAfterAdvice() { return false; }}

AspectJAfterAdvice 简介

包装AspectJ最终通知方法的Spring AOP Advice;

核心代码

public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable { @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } finally { // 不管是否正常返回都会执行通知 invokeAdviceMethod(getJoinPointMatch(), null, null); } } @Override public boolean isBeforeAdvice() { return false; } @Override public boolean isAfterAdvice() { return true; }}

AspectJAfterReturningAdvice 简介

包装AspectJ后置通知方法的Spring AOP Advice;

核心代码

public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implements AfterReturningAdvice, AfterAdvice, Serializable { @Override public boolean isBeforeAdvice() { return false; } @Override public boolean isAfterAdvice() { return true; } @Override public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable { // 根据返回值判断是否调用 if (shouldInvokeOnReturnValueOf(method, returnValue)) { invokeAdviceMethod(getJoinPointMatch(), returnValue, null); } } private boolean shouldInvokeOnReturnValueOf(Method method, @Nullable Object returnValue) { Class<?> type = getDiscoveredReturningType(); Type genericType = getDiscoveredReturningGenericType(); // If we aren't dealing with a raw type, check if generic parameters are assignable. // 判断返回值类型是否匹配,如果返回值类型是泛型类型,则泛型参数也要匹配 return (matchesReturnValue(type, method, returnValue) && (genericType == null || genericType == type || TypeUtils.isAssignable(genericType, method.getGenericReturnType()))); } private boolean matchesReturnValue(Class<?> type, Method method, @Nullable Object returnValue) { if (returnValue != null) { // 返回值是否是指定类型type return ClassUtils.isAssignablevalue(type, returnValue); } else if (Object.class == type && void.class == method.getReturnType()) { // 方法无返回值也会匹配Object类型 return true; } else { // 方法返回值类型是否匹配指定类型type return ClassUtils.isAssignable(type, method.getReturnType()); } }}

AspectJAfterThrowingAdvice 简介

包装AspectJ抛出异常通知方法的Spring AOP Advice;

核心代码

public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable { @Override public boolean isBeforeAdvice() { return false; } @Override public boolean isAfterAdvice() { return true; } @Override public void setThrowingName(String name) { setThrowingNameNoCheck(name); } @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } catch (Throwable ex) { // 根据异常类型判断是否调用 if (shouldInvokeOnThrowing(ex)) { invokeAdviceMethod(getJoinPointMatch(), null, ex); } throw ex; } } private boolean shouldInvokeOnThrowing(Throwable ex) { // 当前发生的异常是否匹配指定异常类型 return getDiscoveredThrowingType().isAssignableFrom(ex.getClass()); }}

AspectJAroundAdvice 简介

包装AspectJ环绕通知方法的Spring AOP Advice;

核心代码

public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable { @Override public boolean isBeforeAdvice() { return false; } @Override public boolean isAfterAdvice() { return false; } @Override protected boolean supportsProceedingJoinPoint() { return true; } @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { if (!(mi instanceof ProxyMethodInvocation)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi); JoinPointMatch jpm = getJoinPointMatch(pmi); return invokeAdviceMethod(pjp, jpm, null, null); } protected ProceedingJoinPoint lazyGetProceedingJoinPoint(ProxyMethodInvocation rmi) { return new MethodInvocationProceedingJoinPoint(rmi); }}

MethodInterceptor 简介

在到达目标的途中拦截接口的调用,子类实现在接口调用之前和之后执行额外处理逻辑;

核心代码

@FunctionalInterfacepublic interface MethodInterceptor extends Interceptor { // 调用方法调用,可以在方法调用之前和之后执行额外逻辑 @Nullable Object invoke(@Nonnull MethodInvocation invocation) throws Throwable;}

ConstructorInterceptor 简介

拦截构造方法,子类实现在构造方法调用之前和之后执行额外处理逻辑;

核心方法

public interface ConstructorInterceptor extends Interceptor { // 调用构造方法调用,可以在构造方法调用之前和之后执行额外逻辑 @Nonnull Object construct(ConstructorInvocation invocation) throws Throwable;}

MethodBeforeAdviceInterceptor 简介

包装MethodBeforeAdvice的Interceptor;

核心代码

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable { // 前置通知 private final MethodBeforeAdvice advice; public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { // 校验前置通知 Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { // 先执行前置通知逻辑 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); // 再执行方法调用 return mi.proceed(); }}

AfterReturningAdviceInterceptor 简介

包装AfterReturningAdvice的Interceptor;

核心代码

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable { // 后置通知 private final AfterReturningAdvice advice; public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) { // 校验后置通知 Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { // 先执行方法调用 Object retVal = mi.proceed(); // 再执行后置通知逻辑 this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; }}

ThrowsAdviceInterceptor 简介

包装ThrowsAdvice的Interceptor;
ThrowsAdvice实现子类中的异常处理方法的签名必须是以下格式:
void afterThrowing([Method, args, target], ThrowableSubclass);
比如:

public void afterThrowing(Exception ex)public void afterThrowing(RemoteException)public void afterThrowing(Method method, Object[] args, Object target, Exception ex)public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)

核心代码

public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice { private static final String AFTER_THROWING = "afterThrowing"; // 抛出异常增强 private final Object throwsAdvice; // 缓存异常处理方法,以异常类型为KEY private final Map, Method> exceptionHandlerMap = new HashMap<>(); public ThrowsAdviceInterceptor(Object throwsAdvice) { // 校验抛出异常增强 Assert.notNull(throwsAdvice, "Advice must not be null"); this.throwsAdvice = throwsAdvice; Method[] methods = throwsAdvice.getClass().getMethods(); // 遍历抛出异常增强的所有方法,寻找异常处理方法 for (Method method : methods) { if (method.getName().equals(AFTER_THROWING) && (method.getParameterCount() == 1 || method.getParameterCount() == 4)) { Class<?> throwableParam = method.getParameterTypes()[method.getParameterCount() - 1]; if (Throwable.class.isAssignableFrom(throwableParam)) { // 缓存异常处理方法,方便直接根据异常类型直接获取异常处理方法 this.exceptionHandlerMap.put(throwableParam, method); if (logger.isDebugEnabled()) { logger.debug("Found exception handler method on throws advice: " + method); } } } } // 校验异常处理方法有效性 if (this.exceptionHandlerMap.isEmpty()) { throw new IllegalArgumentException( "At least one handler method must be found in class [" + throwsAdvice.getClass() + "]"); } } @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { try { // 执行方法调用 return mi.proceed(); } catch (Throwable ex) { // 发生异常,则根据异常类型获取对应的异常处理方法进行处理 Method handlerMethod = getExceptionHandler(ex); if (handlerMethod != null) { invokeHandlerMethod(mi, ex, handlerMethod); } throw ex; } } @Nullable private Method getExceptionHandler(Throwable exception) { Class<?> exceptionClass = exception.getClass(); if (logger.isTraceEnabled()) { logger.trace("Trying to find handler for exception of type [" + exceptionClass.getName() + "]"); } Method handler = this.exceptionHandlerMap.get(exceptionClass); while (handler == null && exceptionClass != Throwable.class) { // 当前异常类型未找到对应的异常处理方法,则继续根据其父类进行查找 exceptionClass = exceptionClass.getSuperclass(); handler = this.exceptionHandlerMap.get(exceptionClass); } if (handler != null && logger.isTraceEnabled()) { logger.trace("Found handler for exception of type [" + exceptionClass.getName() + "]: " + handler); } return handler; } private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable { Object[] handlerArgs; // 准备方法参数 if (method.getParameterCount() == 1) { handlerArgs = new Object[] {ex}; } else { handlerArgs = new Object[] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex}; } try { // 调用异常处理方法 method.invoke(this.throwsAdvice, handlerArgs); } catch (InvocationTargetException targetEx) { throw targetEx.getTargetException(); } }}

AsyncExecutionInterceptor 简介

使用AsyncTaskExecutor异步执行方法调用的AOP MethodInterceptor;

核心代码

public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport implements MethodInterceptor, Ordered { @Override @Nullable public Object invoke(final MethodInvocation invocation) throws Throwable { Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass); final Method userDeclaredMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); // 获取方法调用对应的执行器 AsyncTaskExecutor executor = determineAsyncExecutor(userDeclaredMethod); if (executor == null) { // 执行器必须存在,否则直接抛出异常 throw new IllegalStateException( "No executor specified and no default executor set on AsyncExecutionInterceptor either"); } // 封装方法调用为异步任务 Callable task = () -> { try { // 调用方法调用 Object result = invocation.proceed(); if (result instanceof Future) { // 等待返回值 return ((Future<?>) result).get(); } } catch (ExecutionException ex) { // 异常处理 handleError(ex.getCause(), userDeclaredMethod, invocation.getArguments()); } catch (Throwable ex) { // 异常处理 handleError(ex, userDeclaredMethod, invocation.getArguments()); } return null; }; // 提交异步任务 return doSubmit(task, executor, invocation.getMethod().getReturnType()); }}

CacheInterceptor 简介

支持Spring声明式缓存管理的AOP MethodInterceptor;

核心代码

public class CacheInterceptor extends CacheAspectSupport implements MethodInterceptor, Serializable { @Override @Nullable public Object invoke(final MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); // 封装方法调用为缓存操作调用 CacheOperationInvoker aopAllianceInvoker = () -> { try { // 调用方法调用 return invocation.proceed(); } catch (Throwable ex) { throw new CacheOperationInvoker.ThrowableWrapper(ex); } }; // 获取目标对象 Object target = invocation.getThis(); Assert.state(target != null, "Target must not be null"); try { // 执行缓存操作调用 return execute(aopAllianceInvoker, target, method, invocation.getArguments()); } catch (CacheOperationInvoker.ThrowableWrapper th) { throw th.getOriginal(); } }}

TransactionInterceptor 简介

支持Spring声明式事务管理的AOP MethodInterceptor;

核心代码

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable { @Override @Nullable public Object invoke(MethodInvocation invocation) throws Throwable { // Work out the target class: may be {@code null}. // The TransactionAttributeSource should be passed the target class // as well as the method, which may be from an interface. Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); // Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() { @Override @Nullable public Object proceedWithInvocation() throws Throwable { // 调用方法调用 return invocation.proceed(); } @Override public Object getTarget() { return invocation.getThis(); } @Override public Object[] getArguments() { return invocation.getArguments(); } }); }}

AbstractTraceInterceptor 简介

日志跟踪的基础MethodInterceptor实现;

核心代码

public abstract class AbstractTraceInterceptor implements MethodInterceptor, Serializable { @Override @Nullable public Object invoke(MethodInvocation invocation) throws Throwable { // 获取Log Log logger = getLoggerForInvocation(invocation); if (isInterceptorEnabled(invocation, logger)) { // 日志跟踪调用 return invokeUnderTrace(invocation, logger); } else { // 调用方法调用 return invocation.proceed(); } } // 实现子类确保方法调用一定被调用,可以在方法调用前后执行日志跟踪 @Nullable protected abstract Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable;}

ExposeInvocationInterceptor 简介

将当前MethodInvocation放到当前线程对应的ThreadLocalMap里,当作一个线程本地变量;
如果使用的话,ExposeInvocationInterceptor正常都是在拦截器链首位;

核心代码

public final class ExposeInvocationInterceptor implements MethodInterceptor, PriorityOrdered, Serializable { // 单例 public static final ExposeInvocationInterceptor INSTANCE = new ExposeInvocationInterceptor(); private static final ThreadLocal invocation = new NamedThreadLocal<>("Current AOP method invocation"); // 获取当前MethodInvocation public static MethodInvocation currentInvocation() throws IllegalStateException { MethodInvocation mi = invocation.get(); if (mi == null) { throw new IllegalStateException( "No MethodInvocation found: Check that an AOP invocation is in progress and that the " + "ExposeInvocationInterceptor is upfront in the interceptor chain、Specifically, note that " + "advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor! " + "In addition, ExposeInvocationInterceptor and ExposeInvocationInterceptor.currentInvocation() " + "must be invoked from the same thread."); } return mi; } // 确保单例 private ExposeInvocationInterceptor() { } @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { // 缓存当前MethodInvocation MethodInvocation oldInvocation = invocation.get(); // 更新当前MethodInvocation invocation.set(mi); try { // 调用方法调用 return mi.proceed(); } finally { // 还原当前MethodInvocation invocation.set(oldInvocation); } }}

DelegatingIntroductionInterceptor 简介

支持引介功能的AOP MethodInterceptor;

核心代码

public class DelegatingIntroductionInterceptor extends IntroductionInfoSupport implements IntroductionInterceptor { @Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { if (isMethodOnIntroducedInterface(mi)) { Object retVal = AopUtils.invokeJoinpointUsingReflection(this.delegate, mi.getMethod(), mi.getArguments()); // 如果返回值就是delegate本身,那么真实想返回的应该是proxy if (retVal == this.delegate && mi instanceof ProxyMethodInvocation) { Object proxy = ((ProxyMethodInvocation) mi).getProxy(); if (mi.getMethod().getReturnType().isInstance(proxy)) { retVal = proxy; } } return retVal; } return doProceed(mi); } @Nullable protected Object doProceed(MethodInvocation mi) throws Throwable { // 调用方法调用 return mi.proceed(); }}

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。