Skip to content

Commit

Permalink
MethodBeforeAdviceInterceptor implements BeforeAdvice marker interface
Browse files Browse the repository at this point in the history
Includes related polishing in the advice interceptor implementations.

Issue: SPR-17088

(cherry picked from commit 4e03d3f)
  • Loading branch information
jhoeller committed Jul 25, 2018
1 parent c89fb74 commit d7cf2c8
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -31,6 +31,8 @@
* to use this class directly.
*
* @author Rod Johnson
* @see MethodBeforeAdviceInterceptor
* @see ThrowsAdviceInterceptor
*/
@SuppressWarnings("serial")
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
Expand All @@ -47,6 +49,7 @@ public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
this.advice = advice;
}


@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,6 +21,7 @@
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.util.Assert;

Expand All @@ -30,11 +31,13 @@
* to use this class directly.
*
* @author Rod Johnson
* @see AfterReturningAdviceInterceptor
* @see ThrowsAdviceInterceptor
*/
@SuppressWarnings("serial")
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {

private MethodBeforeAdvice advice;
private final MethodBeforeAdvice advice;


/**
Expand All @@ -46,6 +49,7 @@ public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
this.advice = advice;
}


@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -51,6 +51,8 @@
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see MethodBeforeAdviceInterceptor
* @see AfterReturningAdviceInterceptor
*/
public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {

Expand All @@ -67,9 +69,8 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {

/**
* Create a new ThrowsAdviceInterceptor for the given ThrowsAdvice.
* @param throwsAdvice the advice object that defines the exception
* handler methods (usually a {@link org.springframework.aop.ThrowsAdvice}
* implementation)
* @param throwsAdvice the advice object that defines the exception handler methods
* (usually a {@link org.springframework.aop.ThrowsAdvice} implementation)
*/
public ThrowsAdviceInterceptor(Object throwsAdvice) {
Assert.notNull(throwsAdvice, "Advice must not be null");
Expand All @@ -78,13 +79,14 @@ public ThrowsAdviceInterceptor(Object throwsAdvice) {
Method[] methods = throwsAdvice.getClass().getMethods();
for (Method method : methods) {
if (method.getName().equals(AFTER_THROWING) &&
(method.getParameterCount() == 1 || method.getParameterCount() == 4) &&
Throwable.class.isAssignableFrom(method.getParameterTypes()[method.getParameterCount() - 1])
) {
// Have an exception handler
this.exceptionHandlerMap.put(method.getParameterTypes()[method.getParameterCount() - 1], method);
if (logger.isDebugEnabled()) {
logger.debug("Found exception handler method: " + method);
(method.getParameterCount() == 1 || method.getParameterCount() == 4)) {
Class<?> throwableParam = method.getParameterTypes()[method.getParameterCount() - 1];
if (Throwable.class.isAssignableFrom(throwableParam)) {
// An exception handler to register...
this.exceptionHandlerMap.put(throwableParam, method);
if (logger.isDebugEnabled()) {
logger.debug("Found exception handler method on throws advice: " + method);
}
}
}
}
Expand All @@ -95,14 +97,33 @@ public ThrowsAdviceInterceptor(Object throwsAdvice) {
}
}


/**
* Return the number of handler methods in this advice.
*/
public int getHandlerMethodCount() {
return this.exceptionHandlerMap.size();
}


@Override
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;
}
}

/**
* Determine the exception handle method. Can return null if not found.
* Determine the exception handle method for the given exception.
* @param exception the exception thrown
* @return a handler for the given exception type
* @return a handler for the given exception type, or {@code null} if none found
*/
@Nullable
private Method getExceptionHandler(Throwable exception) {
Expand All @@ -121,24 +142,10 @@ private Method getExceptionHandler(Throwable exception) {
return handler;
}

@Override
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;
}
}

private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable {
Object[] handlerArgs;
if (method.getParameterCount() == 1) {
handlerArgs = new Object[] { ex };
handlerArgs = new Object[] {ex};
}
else {
handlerArgs = new Object[] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex};
Expand Down

0 comments on commit d7cf2c8

Please sign in to comment.