DATACMNS-1556 - Limit default method invocation only to interfaces that actually declare default methods.

This commit is contained in:
Mark Paluch
2019-07-23 10:48:06 +02:00
committed by Oliver Drotbohm
parent 293bbd9a63
commit 972449ef2d
2 changed files with 25 additions and 2 deletions

View File

@@ -26,6 +26,7 @@ import java.util.Map;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.data.util.Lazy;
import org.springframework.lang.Nullable;
@@ -45,6 +46,26 @@ public class DefaultMethodInvokingMethodInterceptor implements MethodInterceptor
private final MethodHandleLookup methodHandleLookup = MethodHandleLookup.getMethodHandleLookup();
private final Map<Method, MethodHandle> methodHandleCache = new ConcurrentReferenceHashMap<>(10, ReferenceType.WEAK);
/**
* Returns whether the {@code interfaceClass} declares {@link Method#isDefault() default methods}.
*
* @param interfaceClass the {@link Class} to inspect.
* @return {@literal true} if {@code interfaceClass} declares a default method.
* @since 2.2
*/
public static boolean hasDefaultMethods(Class<?> interfaceClass) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(interfaceClass);
for (Method method : methods) {
if (method.isDefault()) {
return true;
}
}
return false;
}
/*
* (non-Javadoc)
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)

View File

@@ -35,6 +35,7 @@ import java.util.stream.Collectors;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.beans.BeanUtils;
@@ -310,12 +311,13 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware,
result.addAdvice(new MethodInvocationValidator());
}
result.addAdvice(SurroundingTransactionDetectorMethodInterceptor.INSTANCE);
result.addAdvisor(ExposeInvocationInterceptor.ADVISOR);
postProcessors.forEach(processor -> processor.postProcess(result, information));
result.addAdvice(new DefaultMethodInvokingMethodInterceptor());
if (DefaultMethodInvokingMethodInterceptor.hasDefaultMethods(repositoryInterface)) {
result.addAdvice(new DefaultMethodInvokingMethodInterceptor());
}
ProjectionFactory projectionFactory = getProjectionFactory(classLoader, beanFactory);
result.addAdvice(new QueryExecutorMethodInterceptor(information, projectionFactory));