相关阅读
简介
表示通知
的标签接口,通知
的实现类可以多种,比如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
简介
在到达目标的途中拦截接口的调用,子类实现在接口调用之前和之后执行额外处理逻辑;
核心代码
@FunctionalInterface
public 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<Class<?>, 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<Object> 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<MethodInvocation> 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();
}
}