Polishing

This commit is contained in:
Juergen Hoeller 2018-07-18 14:27:16 +02:00
parent cab35aa788
commit 5fcfe0fa8e
6 changed files with 42 additions and 28 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -27,11 +27,11 @@ import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor; import org.springframework.aop.Advisor;
import org.springframework.aop.IntroductionAdvisor; import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.IntroductionAwareMethodMatcher;
import org.springframework.aop.MethodMatcher; import org.springframework.aop.MethodMatcher;
import org.springframework.aop.PointcutAdvisor; import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry; import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry; import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
import org.springframework.aop.support.MethodMatchers;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
@ -53,19 +53,30 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
// This is somewhat tricky... We have to process introductions first, // This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list. // but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
for (Advisor advisor : config.getAdvisors()) { for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) { if (advisor instanceof PointcutAdvisor) {
// Add it conditionally. // Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) { boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, targetClass, hasIntroductions);
}
else {
match = mm.matches(method, targetClass);
}
if (match) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) { if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method // Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains. // isn't a problem as we normally cache created chains.
@ -98,9 +109,8 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
/** /**
* Determine whether the Advisors contain matching introductions. * Determine whether the Advisors contain matching introductions.
*/ */
private static boolean hasMatchingIntroductions(Advised config, Class<?> actualClass) { private static boolean hasMatchingIntroductions(Advisor[] advisors, Class<?> actualClass) {
for (int i = 0; i < config.getAdvisors().length; i++) { for (Advisor advisor : advisors) {
Advisor advisor = config.getAdvisors()[i];
if (advisor instanceof IntroductionAdvisor) { if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor; IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (ia.getClassFilter().matches(actualClass)) { if (ia.getClassFilter().matches(actualClass)) {

View File

@ -31,15 +31,15 @@ import org.springframework.aop.Advisor;
public interface AdvisorAdapterRegistry { public interface AdvisorAdapterRegistry {
/** /**
* Return an Advisor wrapping the given advice. * Return an {@link Advisor} wrapping the given advice.
* <p>Should by default at least support * <p>Should by default at least support
* {@link org.aopalliance.intercept.MethodInterceptor}, * {@link org.aopalliance.intercept.MethodInterceptor},
* {@link org.springframework.aop.MethodBeforeAdvice}, * {@link org.springframework.aop.MethodBeforeAdvice},
* {@link org.springframework.aop.AfterReturningAdvice}, * {@link org.springframework.aop.AfterReturningAdvice},
* {@link org.springframework.aop.ThrowsAdvice}. * {@link org.springframework.aop.ThrowsAdvice}.
* @param advice object that should be an advice * @param advice an object that should be an advice
* @return an Advisor wrapping the given advice. Never returns {@code null}. * @return an Advisor wrapping the given advice (never {@code null};
* If the advice parameter is an Advisor, return it. * if the advice parameter is an Advisor, it is to be returned as-is)
* @throws UnknownAdviceTypeException if no registered advisor adapter * @throws UnknownAdviceTypeException if no registered advisor adapter
* can wrap the supposed advice * can wrap the supposed advice
*/ */
@ -48,21 +48,20 @@ public interface AdvisorAdapterRegistry {
/** /**
* Return an array of AOP Alliance MethodInterceptors to allow use of the * Return an array of AOP Alliance MethodInterceptors to allow use of the
* given Advisor in an interception-based framework. * given Advisor in an interception-based framework.
* <p>Don't worry about the pointcut associated with the Advisor, * <p>Don't worry about the pointcut associated with the {@link Advisor}, if it is
* if it's a PointcutAdvisor: just return an interceptor. * a {@link org.springframework.aop.PointcutAdvisor}: just return an interceptor.
* @param advisor the Advisor to find an interceptor for * @param advisor the Advisor to find an interceptor for
* @return an array of MethodInterceptors to expose this Advisor's behavior * @return an array of MethodInterceptors to expose this Advisor's behavior
* @throws UnknownAdviceTypeException if the Advisor type is * @throws UnknownAdviceTypeException if the Advisor type is
* not understood by any registered AdvisorAdapter. * not understood by any registered AdvisorAdapter
*/ */
MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException; MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException;
/** /**
* Register the given AdvisorAdapter. Note that it is not necessary to register * Register the given {@link AdvisorAdapter}. Note that it is not necessary to register
* adapters for an AOP Alliance Interceptors or Spring Advices: these must be * adapters for an AOP Alliance Interceptors or Spring Advices: these must be
* automatically recognized by an AdvisorAdapterRegistry implementation. * automatically recognized by an {@code AdvisorAdapterRegistry} implementation.
* @param adapter the AdvisorAdapter that understands a particular Advisor * @param adapter an AdvisorAdapter that understands particular Advisor or Advice types
* or Advice types
*/ */
void registerAdvisorAdapter(AdvisorAdapter adapter); void registerAdvisorAdapter(AdvisorAdapter adapter);

View File

@ -41,6 +41,7 @@ public class BeanFactoryJCacheOperationSourceAdvisor extends AbstractBeanFactory
} }
}; };
/** /**
* Set the cache operation attribute source which is used to find cache * Set the cache operation attribute source which is used to find cache
* attributes. This should usually be identical to the source reference * attributes. This should usually be identical to the source reference

View File

@ -29,8 +29,8 @@ import org.springframework.lang.Nullable;
* @since 4.1 * @since 4.1
* @param <A> the annotation type * @param <A> the annotation type
*/ */
class DefaultCacheKeyInvocationContext<A extends Annotation> class DefaultCacheKeyInvocationContext<A extends Annotation> extends DefaultCacheInvocationContext<A>
extends DefaultCacheInvocationContext<A> implements CacheKeyInvocationContext<A> { implements CacheKeyInvocationContext<A> {
private final CacheInvocationParameter[] keyParameters; private final CacheInvocationParameter[] keyParameters;

View File

@ -857,7 +857,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
Assert.state(target != null, "No target to validate"); Assert.state(target != null, "No target to validate");
BindingResult bindingResult = getBindingResult(); BindingResult bindingResult = getBindingResult();
// Call each validator with the same binding result // Call each validator with the same binding result
for (Validator validator : this.validators) { for (Validator validator : getValidators()) {
validator.validate(target, bindingResult); validator.validate(target, bindingResult);
} }
} }

View File

@ -309,8 +309,9 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
for (int i = 0; i < paramNames.length; i++) { for (int i = 0; i < paramNames.length; i++) {
String paramName = paramNames[i]; String paramName = paramNames[i];
if (!failedParams.contains(paramName)) { if (!failedParams.contains(paramName)) {
result.recordFieldValue(paramName, paramTypes[i], args[i]); Object value = args[i];
validateValueIfApplicable(binder, parameter, ctor.getDeclaringClass(), paramName, args[i]); result.recordFieldValue(paramName, paramTypes[i], value);
validateValueIfApplicable(binder, parameter, ctor.getDeclaringClass(), paramName, value);
} }
} }
throw new BindException(result); throw new BindException(result);
@ -410,7 +411,10 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class); Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) { if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann)); Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
return (hints instanceof Object[] ? (Object[]) hints : new Object[]{hints}); if (hints == null) {
return new Object[0];
}
return (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
} }
return null; return null;
} }