diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAdvisorChainFactory.java b/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAdvisorChainFactory.java index decf2e55a3e..586051bc78a 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAdvisorChainFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAdvisorChainFactory.java @@ -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"); * 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.IntroductionAdvisor; +import org.springframework.aop.IntroductionAwareMethodMatcher; import org.springframework.aop.MethodMatcher; import org.springframework.aop.PointcutAdvisor; import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry; import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry; -import org.springframework.aop.support.MethodMatchers; 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, // but we need to preserve order in the ultimate list. - List interceptorList = new ArrayList<>(config.getAdvisors().length); - Class actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); - boolean hasIntroductions = hasMatchingIntroductions(config, actualClass); AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); + Advisor[] advisors = config.getAdvisors(); + List 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) { // Add it conditionally. PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { - MethodInterceptor[] interceptors = registry.getInterceptors(advisor); 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()) { // Creating a new object instance in the getInterceptors() method // 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. */ - private static boolean hasMatchingIntroductions(Advised config, Class actualClass) { - for (int i = 0; i < config.getAdvisors().length; i++) { - Advisor advisor = config.getAdvisors()[i]; + private static boolean hasMatchingIntroductions(Advisor[] advisors, Class actualClass) { + for (Advisor advisor : advisors) { if (advisor instanceof IntroductionAdvisor) { IntroductionAdvisor ia = (IntroductionAdvisor) advisor; if (ia.getClassFilter().matches(actualClass)) { diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/adapter/AdvisorAdapterRegistry.java b/spring-aop/src/main/java/org/springframework/aop/framework/adapter/AdvisorAdapterRegistry.java index f15353e5b06..4183ec8c4fe 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/adapter/AdvisorAdapterRegistry.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/adapter/AdvisorAdapterRegistry.java @@ -31,15 +31,15 @@ import org.springframework.aop.Advisor; public interface AdvisorAdapterRegistry { /** - * Return an Advisor wrapping the given advice. + * Return an {@link Advisor} wrapping the given advice. *

Should by default at least support * {@link org.aopalliance.intercept.MethodInterceptor}, * {@link org.springframework.aop.MethodBeforeAdvice}, * {@link org.springframework.aop.AfterReturningAdvice}, * {@link org.springframework.aop.ThrowsAdvice}. - * @param advice object that should be an advice - * @return an Advisor wrapping the given advice. Never returns {@code null}. - * If the advice parameter is an Advisor, return it. + * @param advice an object that should be an advice + * @return an Advisor wrapping the given advice (never {@code null}; + * if the advice parameter is an Advisor, it is to be returned as-is) * @throws UnknownAdviceTypeException if no registered advisor adapter * can wrap the supposed advice */ @@ -48,21 +48,20 @@ public interface AdvisorAdapterRegistry { /** * Return an array of AOP Alliance MethodInterceptors to allow use of the * given Advisor in an interception-based framework. - *

Don't worry about the pointcut associated with the Advisor, - * if it's a PointcutAdvisor: just return an interceptor. + *

Don't worry about the pointcut associated with the {@link Advisor}, if it is + * a {@link org.springframework.aop.PointcutAdvisor}: just return an interceptor. * @param advisor the Advisor to find an interceptor for * @return an array of MethodInterceptors to expose this Advisor's behavior * @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; /** - * 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 - * automatically recognized by an AdvisorAdapterRegistry implementation. - * @param adapter the AdvisorAdapter that understands a particular Advisor - * or Advice types + * automatically recognized by an {@code AdvisorAdapterRegistry} implementation. + * @param adapter an AdvisorAdapter that understands particular Advisor or Advice types */ void registerAdvisorAdapter(AdvisorAdapter adapter); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/BeanFactoryJCacheOperationSourceAdvisor.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/BeanFactoryJCacheOperationSourceAdvisor.java index 60e5f49a15d..df81c605aa3 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/BeanFactoryJCacheOperationSourceAdvisor.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/BeanFactoryJCacheOperationSourceAdvisor.java @@ -41,6 +41,7 @@ public class BeanFactoryJCacheOperationSourceAdvisor extends AbstractBeanFactory } }; + /** * Set the cache operation attribute source which is used to find cache * attributes. This should usually be identical to the source reference diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheKeyInvocationContext.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheKeyInvocationContext.java index 1c49ea4e21c..20513504a4a 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheKeyInvocationContext.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultCacheKeyInvocationContext.java @@ -29,8 +29,8 @@ import org.springframework.lang.Nullable; * @since 4.1 * @param the annotation type */ -class DefaultCacheKeyInvocationContext - extends DefaultCacheInvocationContext implements CacheKeyInvocationContext { +class DefaultCacheKeyInvocationContext extends DefaultCacheInvocationContext + implements CacheKeyInvocationContext { private final CacheInvocationParameter[] keyParameters; diff --git a/spring-context/src/main/java/org/springframework/validation/DataBinder.java b/spring-context/src/main/java/org/springframework/validation/DataBinder.java index ab62c932ba1..c9c0e4acdaa 100644 --- a/spring-context/src/main/java/org/springframework/validation/DataBinder.java +++ b/spring-context/src/main/java/org/springframework/validation/DataBinder.java @@ -857,7 +857,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { Assert.state(target != null, "No target to validate"); BindingResult bindingResult = getBindingResult(); // Call each validator with the same binding result - for (Validator validator : this.validators) { + for (Validator validator : getValidators()) { validator.validate(target, bindingResult); } } diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java index e74b7d4fcf3..03709debf26 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java @@ -309,8 +309,9 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol for (int i = 0; i < paramNames.length; i++) { String paramName = paramNames[i]; if (!failedParams.contains(paramName)) { - result.recordFieldValue(paramName, paramTypes[i], args[i]); - validateValueIfApplicable(binder, parameter, ctor.getDeclaringClass(), paramName, args[i]); + Object value = args[i]; + result.recordFieldValue(paramName, paramTypes[i], value); + validateValueIfApplicable(binder, parameter, ctor.getDeclaringClass(), paramName, value); } } throw new BindException(result); @@ -410,7 +411,10 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class); if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) { 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; }