|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2012 the original author or authors. |
| 2 | + * Copyright 2002-2013 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
@@ -71,12 +71,34 @@ public void afterReturning(Object returnValue, Method method, Object[] args, Obj
|
71 | 71 | * @return whether to invoke the advice method for the given return value
|
72 | 72 | */
|
73 | 73 | private boolean shouldInvokeOnReturnValueOf(Method method, Object returnValue) {
|
74 |
| - Class type = getDiscoveredReturningType(); |
| 74 | + Class<?> type = getDiscoveredReturningType(); |
75 | 75 | Type genericType = getDiscoveredReturningGenericType();
|
76 |
| - // If we aren't dealing with a raw type, check if generic parameters are assignable. |
77 |
| - return (ClassUtils.isAssignableValue(type, returnValue) && |
| 76 | + // If we aren't dealing with a raw type, check if generic parameters are assignable. |
| 77 | + return (matchesReturnValue(type, method, returnValue) && |
78 | 78 | (genericType == null || genericType == type ||
|
79 | 79 | TypeUtils.isAssignable(genericType, method.getGenericReturnType())));
|
80 | 80 | }
|
81 | 81 |
|
| 82 | + /** |
| 83 | + * Following AspectJ semantics, if a return value is null (or return type is void), |
| 84 | + * then the return type of target method should be used to determine whether advice |
| 85 | + * is invoked or not. Also, even if the return type is void, if the type of argument |
| 86 | + * declared in the advice method is Object, then the advice must still get invoked. |
| 87 | + * @param type the type of argument declared in advice method |
| 88 | + * @param method the advice method |
| 89 | + * @param returnValue the return value of the target method |
| 90 | + * @return whether to invoke the advice method for the given return value and type |
| 91 | + */ |
| 92 | + private boolean matchesReturnValue(Class<?> type, Method method, Object returnValue) { |
| 93 | + if (returnValue != null) { |
| 94 | + return ClassUtils.isAssignableValue(type, returnValue); |
| 95 | + } |
| 96 | + else if (type.equals(Object.class) && method.getReturnType().equals(void.class)) { |
| 97 | + return true; |
| 98 | + } |
| 99 | + else{ |
| 100 | + return ClassUtils.isAssignable(type, method.getReturnType()); |
| 101 | + } |
| 102 | + } |
| 103 | + |
82 | 104 | }
|
0 commit comments