Polishing
This commit is contained in:
parent
55563c16b5
commit
c0040a5508
|
|
@ -22,7 +22,6 @@ import java.lang.reflect.Method;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
|
@ -94,7 +93,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
|||
* List of Advisors. If an Advice is added, it will be wrapped
|
||||
* in an Advisor before being added to this List.
|
||||
*/
|
||||
private List<Advisor> advisors = new LinkedList<>();
|
||||
private List<Advisor> advisors = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Array updated on changes to the advisors list, which is easier
|
||||
|
|
@ -474,7 +473,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
|||
* for the given method, based on this configuration.
|
||||
* @param method the proxied method
|
||||
* @param targetClass the target class
|
||||
* @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
|
||||
* @return a List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
|
||||
*/
|
||||
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
|
||||
MethodCacheKey cacheKey = new MethodCacheKey(method);
|
||||
|
|
@ -528,7 +527,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
|||
|
||||
/**
|
||||
* Build a configuration-only copy of this AdvisedSupport,
|
||||
* replacing the TargetSource
|
||||
* replacing the TargetSource.
|
||||
*/
|
||||
AdvisedSupport getConfigurationOnlyCopy() {
|
||||
AdvisedSupport copy = new AdvisedSupport();
|
||||
|
|
|
|||
|
|
@ -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<Object> 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<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) {
|
||||
// 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)) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
* <p>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.
|
||||
* @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.
|
||||
* <p>Don't worry about the pointcut associated with the Advisor,
|
||||
* if it's a PointcutAdvisor: just return an interceptor.
|
||||
* <p>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 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 AdvisorAdapter that understands a particular Advisor
|
||||
* or Advice types
|
||||
* automatically recognized by an {@code AdvisorAdapterRegistry} implementation.
|
||||
* @param adapter AdvisorAdapter that understands particular Advisor or Advice types
|
||||
*/
|
||||
void registerAdvisorAdapter(AdvisorAdapter adapter);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -29,13 +29,13 @@ import org.apache.commons.logging.LogFactory;
|
|||
*/
|
||||
public class SimpleAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
|
||||
|
||||
private final Log logger = LogFactory.getLog(SimpleAsyncUncaughtExceptionHandler.class);
|
||||
private static final Log logger = LogFactory.getLog(SimpleAsyncUncaughtExceptionHandler.class);
|
||||
|
||||
|
||||
@Override
|
||||
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error(String.format("Unexpected error occurred invoking async " +
|
||||
"method '%s'.", method), ex);
|
||||
logger.error("Unexpected error occurred invoking async method: " + method, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -25,6 +25,7 @@ import org.springframework.cache.jcache.interceptor.JCacheOperationSource;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Abstract JSR-107 specific {@code @Configuration} class providing common
|
||||
|
|
@ -37,8 +38,10 @@ import org.springframework.context.annotation.Role;
|
|||
@Configuration
|
||||
public class AbstractJCacheConfiguration extends AbstractCachingConfiguration {
|
||||
|
||||
@Nullable
|
||||
protected CacheResolver exceptionCacheResolver;
|
||||
|
||||
|
||||
@Override
|
||||
protected void useCachingConfigurer(CachingConfigurer config) {
|
||||
super.useCachingConfigurer(config);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -18,6 +18,7 @@ package org.springframework.cache.jcache.config;
|
|||
|
||||
import org.springframework.cache.annotation.CachingConfigurer;
|
||||
import org.springframework.cache.interceptor.CacheResolver;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Extension of {@link CachingConfigurer} for the JSR-107 implementation.
|
||||
|
|
@ -58,6 +59,7 @@ public interface JCacheConfigurer extends CachingConfigurer {
|
|||
* </pre>
|
||||
* See {@link org.springframework.cache.annotation.EnableCaching} for more complete examples.
|
||||
*/
|
||||
@Nullable
|
||||
CacheResolver exceptionCacheResolver();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -18,6 +18,7 @@ package org.springframework.cache.jcache.config;
|
|||
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.interceptor.CacheResolver;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* An extension of {@link CachingConfigurerSupport} that also implements
|
||||
|
|
@ -34,6 +35,7 @@ import org.springframework.cache.interceptor.CacheResolver;
|
|||
public class JCacheConfigurerSupport extends CachingConfigurerSupport implements JCacheConfigurer {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public CacheResolver exceptionCacheResolver() {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,4 +6,9 @@
|
|||
* <p>Provide an extension of the {@code CachingConfigurer} that exposes
|
||||
* the exception cache resolver to use, see {@code JCacheConfigurer}.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.cache.jcache.config;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -49,6 +49,7 @@ abstract class AbstractCacheInterceptor<O extends AbstractJCacheOperation<A>, A
|
|||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
protected abstract Object invoke(CacheOperationInvocationContext<O> context, CacheOperationInvoker invoker)
|
||||
throws Throwable;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public abstract class AbstractFallbackJCacheOperationSource implements JCacheOpe
|
|||
|
||||
|
||||
@Override
|
||||
public JCacheOperation<?> getCacheOperation(Method method, Class<?> targetClass) {
|
||||
public JCacheOperation<?> getCacheOperation(Method method, @Nullable Class<?> targetClass) {
|
||||
MethodClassKey cacheKey = new MethodClassKey(method, targetClass);
|
||||
Object cached = this.cache.get(cacheKey);
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ public abstract class AbstractFallbackJCacheOperationSource implements JCacheOpe
|
|||
}
|
||||
|
||||
@Nullable
|
||||
private JCacheOperation<?> computeCacheOperation(Method method, Class<?> targetClass) {
|
||||
private JCacheOperation<?> computeCacheOperation(Method method, @Nullable Class<?> targetClass) {
|
||||
// Don't allow no-public methods as required.
|
||||
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
|
||||
return null;
|
||||
|
|
@ -113,7 +113,7 @@ public abstract class AbstractFallbackJCacheOperationSource implements JCacheOpe
|
|||
* (or {@code null} if none)
|
||||
*/
|
||||
@Nullable
|
||||
protected abstract JCacheOperation<?> findCacheOperation(Method method, Class<?> targetType);
|
||||
protected abstract JCacheOperation<?> findCacheOperation(Method method, @Nullable Class<?> targetType);
|
||||
|
||||
/**
|
||||
* Should only public methods be allowed to have caching semantics?
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ abstract class AbstractJCacheOperation<A extends Annotation> implements JCacheOp
|
|||
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
* Construct a new {@code AbstractJCacheOperation}.
|
||||
* @param methodDetails the {@link CacheMethodDetails} related to the cached method
|
||||
* @param cacheResolver the cache resolver to resolve regular caches
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -37,6 +37,7 @@ abstract class AbstractKeyCacheInterceptor<O extends AbstractJCacheKeyOperation<
|
|||
super(errorHandler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a key for the specified invocation.
|
||||
* @param context the context of the invocation
|
||||
|
|
@ -56,8 +57,7 @@ abstract class AbstractKeyCacheInterceptor<O extends AbstractJCacheKeyOperation<
|
|||
* @param context the context of the invocation.
|
||||
* @return the related {@code CacheKeyInvocationContext}
|
||||
*/
|
||||
protected CacheKeyInvocationContext<A> createCacheKeyInvocationContext(
|
||||
CacheOperationInvocationContext<O> context) {
|
||||
protected CacheKeyInvocationContext<A> createCacheKeyInvocationContext(CacheOperationInvocationContext<O> context) {
|
||||
return new DefaultCacheKeyInvocationContext<>(context.getOperation(), context.getTarget(), context.getArgs());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -45,7 +45,7 @@ import org.springframework.util.StringUtils;
|
|||
public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJCacheOperationSource {
|
||||
|
||||
@Override
|
||||
protected JCacheOperation<?> findCacheOperation(Method method, Class<?> targetType) {
|
||||
protected JCacheOperation<?> findCacheOperation(Method method, @Nullable Class<?> targetType) {
|
||||
CacheResult cacheResult = method.getAnnotation(CacheResult.class);
|
||||
CachePut cachePut = method.getAnnotation(CachePut.class);
|
||||
CacheRemove cacheRemove = method.getAnnotation(CacheRemove.class);
|
||||
|
|
@ -74,15 +74,16 @@ public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJC
|
|||
}
|
||||
}
|
||||
|
||||
protected CacheDefaults getCacheDefaults(Method method, Class<?> targetType) {
|
||||
@Nullable
|
||||
protected CacheDefaults getCacheDefaults(Method method, @Nullable Class<?> targetType) {
|
||||
CacheDefaults annotation = method.getDeclaringClass().getAnnotation(CacheDefaults.class);
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
return targetType.getAnnotation(CacheDefaults.class);
|
||||
return (targetType != null ? targetType.getAnnotation(CacheDefaults.class) : null);
|
||||
}
|
||||
|
||||
protected CacheResultOperation createCacheResultOperation(Method method, CacheDefaults defaults, CacheResult ann) {
|
||||
protected CacheResultOperation createCacheResultOperation(Method method, @Nullable CacheDefaults defaults, CacheResult ann) {
|
||||
String cacheName = determineCacheName(method, defaults, ann.cacheName());
|
||||
CacheResolverFactory cacheResolverFactory =
|
||||
determineCacheResolverFactory(defaults, ann.cacheResolverFactory());
|
||||
|
|
@ -100,7 +101,7 @@ public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJC
|
|||
return new CacheResultOperation(methodDetails, cacheResolver, keyGenerator, exceptionCacheResolver);
|
||||
}
|
||||
|
||||
protected CachePutOperation createCachePutOperation(Method method, CacheDefaults defaults, CachePut ann) {
|
||||
protected CachePutOperation createCachePutOperation(Method method, @Nullable CacheDefaults defaults, CachePut ann) {
|
||||
String cacheName = determineCacheName(method, defaults, ann.cacheName());
|
||||
CacheResolverFactory cacheResolverFactory =
|
||||
determineCacheResolverFactory(defaults, ann.cacheResolverFactory());
|
||||
|
|
@ -111,7 +112,7 @@ public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJC
|
|||
return new CachePutOperation(methodDetails, cacheResolver, keyGenerator);
|
||||
}
|
||||
|
||||
protected CacheRemoveOperation createCacheRemoveOperation(Method method, CacheDefaults defaults, CacheRemove ann) {
|
||||
protected CacheRemoveOperation createCacheRemoveOperation(Method method, @Nullable CacheDefaults defaults, CacheRemove ann) {
|
||||
String cacheName = determineCacheName(method, defaults, ann.cacheName());
|
||||
CacheResolverFactory cacheResolverFactory =
|
||||
determineCacheResolverFactory(defaults, ann.cacheResolverFactory());
|
||||
|
|
@ -122,7 +123,7 @@ public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJC
|
|||
return new CacheRemoveOperation(methodDetails, cacheResolver, keyGenerator);
|
||||
}
|
||||
|
||||
protected CacheRemoveAllOperation createCacheRemoveAllOperation(Method method, CacheDefaults defaults, CacheRemoveAll ann) {
|
||||
protected CacheRemoveAllOperation createCacheRemoveAllOperation(Method method, @Nullable CacheDefaults defaults, CacheRemoveAll ann) {
|
||||
String cacheName = determineCacheName(method, defaults, ann.cacheName());
|
||||
CacheResolverFactory cacheResolverFactory =
|
||||
determineCacheResolverFactory(defaults, ann.cacheResolverFactory());
|
||||
|
|
@ -136,7 +137,9 @@ public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJC
|
|||
return new DefaultCacheMethodDetails<>(method, annotation, cacheName);
|
||||
}
|
||||
|
||||
protected CacheResolver getCacheResolver(CacheResolverFactory factory, CacheMethodDetails<?> details) {
|
||||
protected CacheResolver getCacheResolver(
|
||||
@Nullable CacheResolverFactory factory, CacheMethodDetails<?> details) {
|
||||
|
||||
if (factory != null) {
|
||||
javax.cache.annotation.CacheResolver cacheResolver = factory.getCacheResolver(details);
|
||||
return new CacheResolverAdapter(cacheResolver);
|
||||
|
|
@ -146,8 +149,8 @@ public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJC
|
|||
}
|
||||
}
|
||||
|
||||
protected CacheResolver getExceptionCacheResolver(CacheResolverFactory factory,
|
||||
CacheMethodDetails<CacheResult> details) {
|
||||
protected CacheResolver getExceptionCacheResolver(
|
||||
@Nullable CacheResolverFactory factory, CacheMethodDetails<CacheResult> details) {
|
||||
|
||||
if (factory != null) {
|
||||
javax.cache.annotation.CacheResolver cacheResolver = factory.getExceptionCacheResolver(details);
|
||||
|
|
@ -159,13 +162,13 @@ public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJC
|
|||
}
|
||||
|
||||
@Nullable
|
||||
protected CacheResolverFactory determineCacheResolverFactory(CacheDefaults defaults,
|
||||
Class<? extends CacheResolverFactory> candidate) {
|
||||
protected CacheResolverFactory determineCacheResolverFactory(
|
||||
@Nullable CacheDefaults defaults, Class<? extends CacheResolverFactory> candidate) {
|
||||
|
||||
if (CacheResolverFactory.class != candidate) {
|
||||
if (candidate != CacheResolverFactory.class) {
|
||||
return getBean(candidate);
|
||||
}
|
||||
else if (defaults != null && CacheResolverFactory.class != defaults.cacheResolverFactory()) {
|
||||
else if (defaults != null && defaults.cacheResolverFactory() != CacheResolverFactory.class) {
|
||||
return getBean(defaults.cacheResolverFactory());
|
||||
}
|
||||
else {
|
||||
|
|
@ -173,8 +176,10 @@ public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJC
|
|||
}
|
||||
}
|
||||
|
||||
protected KeyGenerator determineKeyGenerator(CacheDefaults defaults, Class<? extends CacheKeyGenerator> candidate) {
|
||||
if (CacheKeyGenerator.class != candidate) {
|
||||
protected KeyGenerator determineKeyGenerator(
|
||||
@Nullable CacheDefaults defaults, Class<? extends CacheKeyGenerator> candidate) {
|
||||
|
||||
if (candidate != CacheKeyGenerator.class) {
|
||||
return new KeyGeneratorAdapter(this, getBean(candidate));
|
||||
}
|
||||
else if (defaults != null && CacheKeyGenerator.class != defaults.cacheKeyGenerator()) {
|
||||
|
|
@ -185,7 +190,7 @@ public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJC
|
|||
}
|
||||
}
|
||||
|
||||
protected String determineCacheName(Method method, CacheDefaults defaults, String candidate) {
|
||||
protected String determineCacheName(Method method, @Nullable CacheDefaults defaults, String candidate) {
|
||||
if (StringUtils.hasText(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -19,6 +19,7 @@ package org.springframework.cache.jcache.interceptor;
|
|||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Advisor driven by a {@link JCacheOperationSource}, used to include a
|
||||
|
|
@ -30,6 +31,7 @@ import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
|
|||
@SuppressWarnings("serial")
|
||||
public class BeanFactoryJCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
|
||||
|
||||
@Nullable
|
||||
private JCacheOperationSource cacheOperationSource;
|
||||
|
||||
private final JCacheOperationSourcePointcut pointcut = new JCacheOperationSourcePointcut() {
|
||||
|
|
@ -39,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
|
||||
|
|
@ -61,4 +64,4 @@ public class BeanFactoryJCacheOperationSourceAdvisor extends AbstractBeanFactory
|
|||
return this.pointcut;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -37,16 +37,16 @@ class CachePutInterceptor extends AbstractKeyCacheInterceptor<CachePutOperation,
|
|||
super(errorHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object invoke(CacheOperationInvocationContext<CachePutOperation> context,
|
||||
CacheOperationInvoker invoker) {
|
||||
|
||||
CacheKeyInvocationContext<CachePut> invocationContext = createCacheKeyInvocationContext(context);
|
||||
@Override
|
||||
protected Object invoke(
|
||||
CacheOperationInvocationContext<CachePutOperation> context, CacheOperationInvoker invoker) {
|
||||
|
||||
CachePutOperation operation = context.getOperation();
|
||||
CacheKeyInvocationContext<CachePut> invocationContext = createCacheKeyInvocationContext(context);
|
||||
|
||||
boolean earlyPut = operation.isEarlyPut();
|
||||
Object value = invocationContext.getValueParameter().getValue();
|
||||
|
||||
if (earlyPut) {
|
||||
cacheValue(context, value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -24,6 +24,7 @@ import javax.cache.annotation.CachePut;
|
|||
|
||||
import org.springframework.cache.interceptor.CacheResolver;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ExceptionTypeFilter;
|
||||
|
||||
/**
|
||||
|
|
@ -44,13 +45,17 @@ class CachePutOperation extends AbstractJCacheKeyOperation<CachePut> {
|
|||
CacheMethodDetails<CachePut> methodDetails, CacheResolver cacheResolver, KeyGenerator keyGenerator) {
|
||||
|
||||
super(methodDetails, cacheResolver, keyGenerator);
|
||||
|
||||
CachePut ann = methodDetails.getCacheAnnotation();
|
||||
this.exceptionTypeFilter = createExceptionTypeFilter(ann.cacheFor(), ann.noCacheFor());
|
||||
this.valueParameterDetail = initializeValueParameterDetail(methodDetails.getMethod(), this.allParameterDetails);
|
||||
if (this.valueParameterDetail == null) {
|
||||
|
||||
CacheParameterDetail valueParameterDetail =
|
||||
initializeValueParameterDetail(methodDetails.getMethod(), this.allParameterDetails);
|
||||
if (valueParameterDetail == null) {
|
||||
throw new IllegalArgumentException("No parameter annotated with @CacheValue was found for " +
|
||||
"" + methodDetails.getMethod());
|
||||
methodDetails.getMethod());
|
||||
}
|
||||
this.valueParameterDetail = valueParameterDetail;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -85,6 +90,7 @@ class CachePutOperation extends AbstractJCacheKeyOperation<CachePut> {
|
|||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static CacheParameterDetail initializeValueParameterDetail(
|
||||
Method method, List<CacheParameterDetail> allParameters) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -30,21 +30,20 @@ import org.springframework.cache.interceptor.CacheOperationInvoker;
|
|||
* @since 4.1
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
class CacheRemoveAllInterceptor
|
||||
extends AbstractCacheInterceptor<CacheRemoveAllOperation, CacheRemoveAll> {
|
||||
class CacheRemoveAllInterceptor extends AbstractCacheInterceptor<CacheRemoveAllOperation, CacheRemoveAll> {
|
||||
|
||||
protected CacheRemoveAllInterceptor(CacheErrorHandler errorHandler) {
|
||||
super(errorHandler);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object invoke(CacheOperationInvocationContext<CacheRemoveAllOperation> context,
|
||||
CacheOperationInvoker invoker) {
|
||||
protected Object invoke(
|
||||
CacheOperationInvocationContext<CacheRemoveAllOperation> context, CacheOperationInvoker invoker) {
|
||||
|
||||
CacheRemoveAllOperation operation = context.getOperation();
|
||||
|
||||
boolean earlyRemove = operation.isEarlyRemove();
|
||||
|
||||
if (earlyRemove) {
|
||||
removeAll(context);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -36,13 +36,14 @@ class CacheRemoveEntryInterceptor extends AbstractKeyCacheInterceptor<CacheRemov
|
|||
super(errorHandler);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object invoke(CacheOperationInvocationContext<CacheRemoveOperation> context,
|
||||
CacheOperationInvoker invoker) {
|
||||
protected Object invoke(
|
||||
CacheOperationInvocationContext<CacheRemoveOperation> context, CacheOperationInvoker invoker) {
|
||||
|
||||
CacheRemoveOperation operation = context.getOperation();
|
||||
|
||||
final boolean earlyRemove = operation.isEarlyRemove();
|
||||
|
||||
boolean earlyRemove = operation.isEarlyRemove();
|
||||
if (earlyRemove) {
|
||||
removeValue(context);
|
||||
}
|
||||
|
|
@ -54,12 +55,12 @@ class CacheRemoveEntryInterceptor extends AbstractKeyCacheInterceptor<CacheRemov
|
|||
}
|
||||
return result;
|
||||
}
|
||||
catch (CacheOperationInvoker.ThrowableWrapper t) {
|
||||
Throwable ex = t.getOriginal();
|
||||
catch (CacheOperationInvoker.ThrowableWrapper wrapperException) {
|
||||
Throwable ex = wrapperException.getOriginal();
|
||||
if (!earlyRemove && operation.getExceptionTypeFilter().match(ex.getClass())) {
|
||||
removeValue(context);
|
||||
}
|
||||
throw t;
|
||||
throw wrapperException;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -24,6 +24,7 @@ import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
|||
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
||||
import org.springframework.cache.interceptor.CacheResolver;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ExceptionTypeFilter;
|
||||
import org.springframework.util.SerializationUtils;
|
||||
|
||||
|
|
@ -42,8 +43,9 @@ class CacheResultInterceptor extends AbstractKeyCacheInterceptor<CacheResultOper
|
|||
|
||||
|
||||
@Override
|
||||
protected Object invoke(CacheOperationInvocationContext<CacheResultOperation> context,
|
||||
CacheOperationInvoker invoker) {
|
||||
@Nullable
|
||||
protected Object invoke(
|
||||
CacheOperationInvocationContext<CacheResultOperation> context, CacheOperationInvoker invoker) {
|
||||
|
||||
CacheResultOperation operation = context.getOperation();
|
||||
Object cacheKey = generateKey(context);
|
||||
|
|
@ -74,17 +76,19 @@ class CacheResultInterceptor extends AbstractKeyCacheInterceptor<CacheResultOper
|
|||
/**
|
||||
* Check for a cached exception. If the exception is found, throw it directly.
|
||||
*/
|
||||
protected void checkForCachedException(Cache exceptionCache, Object cacheKey) {
|
||||
protected void checkForCachedException(@Nullable Cache exceptionCache, Object cacheKey) {
|
||||
if (exceptionCache == null) {
|
||||
return;
|
||||
}
|
||||
Cache.ValueWrapper result = doGet(exceptionCache, cacheKey);
|
||||
if (result != null) {
|
||||
throw rewriteCallStack((Throwable) result.get(), getClass().getName(), "invoke");
|
||||
Throwable ex = (Throwable) result.get();
|
||||
Assert.state(ex != null, "No exception in cache");
|
||||
throw rewriteCallStack(ex, getClass().getName(), "invoke");
|
||||
}
|
||||
}
|
||||
|
||||
protected void cacheException(Cache exceptionCache, ExceptionTypeFilter filter, Object cacheKey, Throwable ex) {
|
||||
protected void cacheException(@Nullable Cache exceptionCache, ExceptionTypeFilter filter, Object cacheKey, Throwable ex) {
|
||||
if (exceptionCache == null) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -143,6 +147,7 @@ class CacheResultInterceptor extends AbstractKeyCacheInterceptor<CacheResultOper
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
private static <T extends Throwable> T cloneException(T exception) {
|
||||
try {
|
||||
return (T) SerializationUtils.deserialize(SerializationUtils.serialize(exception));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -36,15 +36,18 @@ class CacheResultOperation extends AbstractJCacheKeyOperation<CacheResult> {
|
|||
|
||||
private final ExceptionTypeFilter exceptionTypeFilter;
|
||||
|
||||
@Nullable
|
||||
private final CacheResolver exceptionCacheResolver;
|
||||
|
||||
@Nullable
|
||||
private final String exceptionCacheName;
|
||||
|
||||
|
||||
public CacheResultOperation(CacheMethodDetails<CacheResult> methodDetails, CacheResolver cacheResolver,
|
||||
KeyGenerator keyGenerator, CacheResolver exceptionCacheResolver) {
|
||||
KeyGenerator keyGenerator, @Nullable CacheResolver exceptionCacheResolver) {
|
||||
|
||||
super(methodDetails, cacheResolver, keyGenerator);
|
||||
|
||||
CacheResult ann = methodDetails.getCacheAnnotation();
|
||||
this.exceptionTypeFilter = createExceptionTypeFilter(ann.cachedExceptions(), ann.nonCachedExceptions());
|
||||
this.exceptionCacheResolver = exceptionCacheResolver;
|
||||
|
|
@ -70,6 +73,7 @@ class CacheResultOperation extends AbstractJCacheKeyOperation<CacheResult> {
|
|||
* Return the {@link CacheResolver} instance to use to resolve the cache to
|
||||
* use for matching exceptions thrown by this operation.
|
||||
*/
|
||||
@Nullable
|
||||
public CacheResolver getExceptionCacheResolver() {
|
||||
return this.exceptionCacheResolver;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -20,21 +20,25 @@ import java.lang.annotation.Annotation;
|
|||
import javax.cache.annotation.CacheInvocationParameter;
|
||||
import javax.cache.annotation.CacheKeyInvocationContext;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* The default {@link CacheKeyInvocationContext} implementation.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
* @param <A> the annotation type
|
||||
*/
|
||||
class DefaultCacheKeyInvocationContext<A extends Annotation>
|
||||
extends DefaultCacheInvocationContext<A> implements CacheKeyInvocationContext<A> {
|
||||
class DefaultCacheKeyInvocationContext<A extends Annotation> extends DefaultCacheInvocationContext<A>
|
||||
implements CacheKeyInvocationContext<A> {
|
||||
|
||||
private final CacheInvocationParameter[] keyParameters;
|
||||
|
||||
@Nullable
|
||||
private final CacheInvocationParameter valueParameter;
|
||||
|
||||
public DefaultCacheKeyInvocationContext(AbstractJCacheKeyOperation<A> operation,
|
||||
Object target, Object[] args) {
|
||||
|
||||
public DefaultCacheKeyInvocationContext(AbstractJCacheKeyOperation<A> operation, Object target, Object[] args) {
|
||||
super(operation, target, args);
|
||||
this.keyParameters = operation.getKeyParameters(args);
|
||||
if (operation instanceof CachePutOperation) {
|
||||
|
|
@ -45,14 +49,16 @@ class DefaultCacheKeyInvocationContext<A extends Annotation>
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CacheInvocationParameter[] getKeyParameters() {
|
||||
return keyParameters.clone();
|
||||
return this.keyParameters.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public CacheInvocationParameter getValueParameter() {
|
||||
return valueParameter;
|
||||
return this.valueParameter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
|
|
@ -46,22 +46,27 @@ import org.springframework.util.Assert;
|
|||
public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSource
|
||||
implements BeanFactoryAware, InitializingBean, SmartInitializingSingleton {
|
||||
|
||||
@Nullable
|
||||
private CacheManager cacheManager;
|
||||
|
||||
@Nullable
|
||||
private CacheResolver cacheResolver;
|
||||
|
||||
@Nullable
|
||||
private CacheResolver exceptionCacheResolver;
|
||||
|
||||
private KeyGenerator keyGenerator = new SimpleKeyGenerator();
|
||||
|
||||
@Nullable
|
||||
private KeyGenerator adaptedKeyGenerator;
|
||||
|
||||
@Nullable
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Set the default {@link CacheManager} to use to lookup cache by name. Only mandatory
|
||||
* if the {@linkplain CacheResolver cache resolvers} have not been set.
|
||||
* Set the default {@link CacheManager} to use to lookup cache by name.
|
||||
* Only mandatory if the {@linkplain CacheResolver cache resolver} has not been set.
|
||||
*/
|
||||
public void setCacheManager(@Nullable CacheManager cacheManager) {
|
||||
this.cacheManager = cacheManager;
|
||||
|
|
@ -112,14 +117,13 @@ public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSourc
|
|||
* honoring the JSR-107 {@link javax.cache.annotation.CacheKey} and
|
||||
* {@link javax.cache.annotation.CacheValue} will be used.
|
||||
*/
|
||||
public void setKeyGenerator(@Nullable KeyGenerator keyGenerator) {
|
||||
public void setKeyGenerator(KeyGenerator keyGenerator) {
|
||||
this.keyGenerator = keyGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the specified key generator to use, if any.
|
||||
* Return the specified key generator to use.
|
||||
*/
|
||||
@Nullable
|
||||
public KeyGenerator getKeyGenerator() {
|
||||
return this.keyGenerator;
|
||||
}
|
||||
|
|
@ -138,13 +142,14 @@ public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSourc
|
|||
@Override
|
||||
public void afterSingletonsInstantiated() {
|
||||
// Make sure that the cache resolver is initialized. An exception cache resolver is only
|
||||
// required if the exceptionCacheName attribute is set on an operation
|
||||
// required if the exceptionCacheName attribute is set on an operation.
|
||||
Assert.notNull(getDefaultCacheResolver(), "Cache resolver should have been initialized");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected <T> T getBean(Class<T> type) {
|
||||
Assert.state(this.beanFactory != null, "BeanFactory required for resolution of [" + type + "]");
|
||||
try {
|
||||
return this.beanFactory.getBean(type);
|
||||
}
|
||||
|
|
@ -162,6 +167,7 @@ public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSourc
|
|||
|
||||
protected CacheManager getDefaultCacheManager() {
|
||||
if (this.cacheManager == null) {
|
||||
Assert.state(this.beanFactory != null, "BeanFactory required for default CacheManager resolution");
|
||||
try {
|
||||
this.cacheManager = this.beanFactory.getBean(CacheManager.class);
|
||||
}
|
||||
|
|
@ -195,21 +201,25 @@ public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSourc
|
|||
|
||||
@Override
|
||||
protected KeyGenerator getDefaultKeyGenerator() {
|
||||
Assert.state(this.adaptedKeyGenerator != null, "KeyGenerator not initialized");
|
||||
return this.adaptedKeyGenerator;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Only resolve the default exception cache resolver when an exception needs to be handled.
|
||||
* <p>A non-JSR-107 setup requires either a {@link CacheManager} or a {@link CacheResolver}. If only
|
||||
* the latter is specified, it is not possible to extract a default exception {@code CacheResolver}
|
||||
* from a custom {@code CacheResolver} implementation so we have to fallback on the {@code CacheManager}.
|
||||
* <p>This gives this weird situation of a perfectly valid configuration that breaks all the sudden
|
||||
* because the JCache support is enabled. To avoid this we resolve the default exception {@code CacheResolver}
|
||||
* as late as possible to avoid such hard requirement in other cases.
|
||||
* <p>A non-JSR-107 setup requires either a {@link CacheManager} or a {@link CacheResolver}.
|
||||
* If only the latter is specified, it is not possible to extract a default exception
|
||||
* {@code CacheResolver} from a custom {@code CacheResolver} implementation so we have to
|
||||
* fall back on the {@code CacheManager}.
|
||||
* <p>This gives this weird situation of a perfectly valid configuration that breaks all
|
||||
* the sudden because the JCache support is enabled. To avoid this we resolve the default
|
||||
* exception {@code CacheResolver} as late as possible to avoid such hard requirement
|
||||
* in other cases.
|
||||
*/
|
||||
class LazyCacheResolver implements CacheResolver {
|
||||
|
||||
@Nullable
|
||||
private CacheResolver cacheResolver;
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -28,6 +28,7 @@ import org.springframework.cache.interceptor.AbstractCacheInvoker;
|
|||
import org.springframework.cache.interceptor.BasicOperation;
|
||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
|
@ -52,19 +53,27 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial
|
|||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@Nullable
|
||||
private JCacheOperationSource cacheOperationSource;
|
||||
|
||||
@Nullable
|
||||
private CacheResultInterceptor cacheResultInterceptor;
|
||||
|
||||
@Nullable
|
||||
private CachePutInterceptor cachePutInterceptor;
|
||||
|
||||
@Nullable
|
||||
private CacheRemoveEntryInterceptor cacheRemoveEntryInterceptor;
|
||||
|
||||
@Nullable
|
||||
private CacheRemoveAllInterceptor cacheRemoveAllInterceptor;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
private CacheResultInterceptor cacheResultInterceptor;
|
||||
|
||||
private CachePutInterceptor cachePutInterceptor;
|
||||
|
||||
private CacheRemoveEntryInterceptor cacheRemoveEntryInterceptor;
|
||||
|
||||
private CacheRemoveAllInterceptor cacheRemoveAllInterceptor;
|
||||
|
||||
|
||||
/**
|
||||
* Set the CacheOperationSource for this cache aspect.
|
||||
*/
|
||||
public void setCacheOperationSource(JCacheOperationSource cacheOperationSource) {
|
||||
Assert.notNull(cacheOperationSource, "JCacheOperationSource must not be null");
|
||||
this.cacheOperationSource = cacheOperationSource;
|
||||
|
|
@ -74,12 +83,13 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial
|
|||
* Return the CacheOperationSource for this cache aspect.
|
||||
*/
|
||||
public JCacheOperationSource getCacheOperationSource() {
|
||||
Assert.state(this.cacheOperationSource != null, "The 'cacheOperationSource' property is required: " +
|
||||
"If there are no cacheable methods, then don't use a cache aspect.");
|
||||
return this.cacheOperationSource;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
Assert.state(getCacheOperationSource() != null, "The 'cacheOperationSource' property is required: " +
|
||||
"If there are no cacheable methods, then don't use a cache aspect.");
|
||||
getCacheOperationSource();
|
||||
|
||||
this.cacheResultInterceptor = new CacheResultInterceptor(getErrorHandler());
|
||||
this.cachePutInterceptor = new CachePutInterceptor(getErrorHandler());
|
||||
|
|
@ -90,6 +100,7 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial
|
|||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
|
||||
// Check whether aspect is enabled to cope with cases where the AJ is pulled in automatically
|
||||
if (this.initialized) {
|
||||
|
|
@ -114,23 +125,28 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
private Object execute(CacheOperationInvocationContext<?> context, CacheOperationInvoker invoker) {
|
||||
CacheOperationInvoker adapter = new CacheOperationInvokerAdapter(invoker);
|
||||
BasicOperation operation = context.getOperation();
|
||||
|
||||
if (operation instanceof CacheResultOperation) {
|
||||
Assert.state(this.cacheResultInterceptor != null, "No CacheResultInterceptor");
|
||||
return this.cacheResultInterceptor.invoke(
|
||||
(CacheOperationInvocationContext<CacheResultOperation>) context, adapter);
|
||||
}
|
||||
else if (operation instanceof CachePutOperation) {
|
||||
Assert.state(this.cachePutInterceptor != null, "No CachePutInterceptor");
|
||||
return this.cachePutInterceptor.invoke(
|
||||
(CacheOperationInvocationContext<CachePutOperation>) context, adapter);
|
||||
}
|
||||
else if (operation instanceof CacheRemoveOperation) {
|
||||
Assert.state(this.cacheRemoveEntryInterceptor != null, "No CacheRemoveEntryInterceptor");
|
||||
return this.cacheRemoveEntryInterceptor.invoke(
|
||||
(CacheOperationInvocationContext<CacheRemoveOperation>) context, adapter);
|
||||
}
|
||||
else if (operation instanceof CacheRemoveAllOperation) {
|
||||
Assert.state(this.cacheRemoveAllInterceptor != null, "No CacheRemoveAllInterceptor");
|
||||
return this.cacheRemoveAllInterceptor.invoke(
|
||||
(CacheOperationInvocationContext<CacheRemoveAllOperation>) context, adapter);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -23,6 +23,7 @@ import org.aopalliance.intercept.MethodInterceptor;
|
|||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* AOP Alliance MethodInterceptor for declarative cache
|
||||
|
|
@ -42,6 +43,7 @@ import org.springframework.cache.interceptor.CacheOperationInvoker;
|
|||
public class JCacheInterceptor extends JCacheAspectSupport implements MethodInterceptor, Serializable {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
||||
Method method = invocation.getMethod();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -33,7 +33,6 @@ public interface JCacheOperationSource {
|
|||
/**
|
||||
* Return the cache operations for this method, or {@code null}
|
||||
* if the method contains no <em>JSR-107</em> related metadata.
|
||||
*
|
||||
* @param method the method to introspect
|
||||
* @param targetClass the target class (may be {@code null}, in which case
|
||||
* the declaring class of the method must be used)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -31,11 +31,10 @@ import org.springframework.util.ObjectUtils;
|
|||
* @since 4.1
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class JCacheOperationSourcePointcut
|
||||
extends StaticMethodMatcherPointcut implements Serializable {
|
||||
public abstract class JCacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
public boolean matches(Method method, @Nullable Class<?> targetClass) {
|
||||
JCacheOperationSource cas = getCacheOperationSource();
|
||||
return (cas != null && cas.getCacheOperation(method, targetClass) != null);
|
||||
}
|
||||
|
|
@ -47,6 +46,7 @@ public abstract class JCacheOperationSourcePointcut
|
|||
@Nullable
|
||||
protected abstract JCacheOperationSource getCacheOperationSource();
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import javax.cache.annotation.CacheKeyGenerator;
|
|||
import javax.cache.annotation.CacheKeyInvocationContext;
|
||||
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
|
@ -34,14 +35,17 @@ import org.springframework.util.CollectionUtils;
|
|||
* so that only relevant parameters are handled.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.1
|
||||
*/
|
||||
class KeyGeneratorAdapter implements KeyGenerator {
|
||||
|
||||
private final JCacheOperationSource cacheOperationSource;
|
||||
|
||||
@Nullable
|
||||
private KeyGenerator keyGenerator;
|
||||
|
||||
@Nullable
|
||||
private CacheKeyGenerator cacheKeyGenerator;
|
||||
|
||||
|
||||
|
|
@ -72,7 +76,11 @@ class KeyGeneratorAdapter implements KeyGenerator {
|
|||
* or a {@link CacheKeyGenerator}.
|
||||
*/
|
||||
public Object getTarget() {
|
||||
return (this.keyGenerator != null ? this.keyGenerator : this.cacheKeyGenerator);
|
||||
if (this.cacheKeyGenerator != null) {
|
||||
return this.cacheKeyGenerator;
|
||||
}
|
||||
Assert.state(this.keyGenerator != null, "No key generator");
|
||||
return this.keyGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -87,6 +95,7 @@ class KeyGeneratorAdapter implements KeyGenerator {
|
|||
return this.cacheKeyGenerator.generateCacheKey(invocationContext);
|
||||
}
|
||||
else {
|
||||
Assert.state(this.keyGenerator != null, "No key generator");
|
||||
return doGenerate(this.keyGenerator, invocationContext);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,9 @@
|
|||
* <p>Builds on the AOP infrastructure in org.springframework.aop.framework.
|
||||
* Any POJO can be cache-advised with Spring.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.cache.jcache.interceptor;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -47,11 +47,11 @@ public class AnnotationCacheOperationSourceTests extends AbstractJCacheTests {
|
|||
|
||||
private final DefaultJCacheOperationSource source = new DefaultJCacheOperationSource();
|
||||
|
||||
private final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
private final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
public void setup() {
|
||||
source.setCacheResolver(defaultCacheResolver);
|
||||
source.setExceptionCacheResolver(defaultExceptionCacheResolver);
|
||||
source.setKeyGenerator(defaultKeyGenerator);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -40,13 +40,13 @@ public class CachingConfigurerSupport implements CachingConfigurer {
|
|||
|
||||
@Override
|
||||
@Nullable
|
||||
public KeyGenerator keyGenerator() {
|
||||
public CacheResolver cacheResolver() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public CacheResolver cacheResolver() {
|
||||
public KeyGenerator keyGenerator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -112,21 +112,21 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
|
|||
*/
|
||||
private static void parseCacheResolution(Element element, BeanDefinition def, boolean setBoth) {
|
||||
String name = element.getAttribute("cache-resolver");
|
||||
if (StringUtils.hasText(name)) {
|
||||
boolean hasText = StringUtils.hasText(name);
|
||||
if (hasText) {
|
||||
def.getPropertyValues().add("cacheResolver", new RuntimeBeanReference(name.trim()));
|
||||
}
|
||||
if (!StringUtils.hasText(name) || setBoth) {
|
||||
if (!hasText || setBoth) {
|
||||
def.getPropertyValues().add("cacheManager",
|
||||
new RuntimeBeanReference(CacheNamespaceHandler.extractCacheManager(element)));
|
||||
}
|
||||
}
|
||||
|
||||
private static BeanDefinition parseErrorHandler(Element element, BeanDefinition def) {
|
||||
private static void parseErrorHandler(Element element, BeanDefinition def) {
|
||||
String name = element.getAttribute("error-handler");
|
||||
if (StringUtils.hasText(name)) {
|
||||
def.getPropertyValues().add("errorHandler", new RuntimeBeanReference(name.trim()));
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -175,12 +175,12 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
|
|||
}
|
||||
|
||||
/**
|
||||
* Registers a
|
||||
* Registers a cache aspect.
|
||||
* <pre class="code">
|
||||
* <bean id="cacheAspect" class="org.springframework.cache.aspectj.AnnotationCacheAspect" factory-method="aspectOf">
|
||||
* <property name="cacheManager" ref="cacheManager"/>
|
||||
* <property name="keyGenerator" ref="keyGenerator"/>
|
||||
* </bean>
|
||||
* <bean id="cacheAspect" class="org.springframework.cache.aspectj.AnnotationCacheAspect" factory-method="aspectOf">
|
||||
* <property name="cacheManager" ref="cacheManager"/>
|
||||
* <property name="keyGenerator" ref="keyGenerator"/>
|
||||
* </bean>
|
||||
* </pre>
|
||||
*/
|
||||
private static void registerCacheAspect(Element element, ParserContext parserContext) {
|
||||
|
|
|
|||
|
|
@ -192,8 +192,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
|||
}
|
||||
catch (NoUniqueBeanDefinitionException ex) {
|
||||
throw new IllegalStateException("No CacheResolver specified, and no unique bean of type " +
|
||||
"CacheManager found. Mark one as primary (or give it the name 'cacheManager') or " +
|
||||
"declare a specific CacheManager to use, that serves as the default one.");
|
||||
"CacheManager found. Mark one as primary or declare a specific CacheManager to use.");
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
throw new IllegalStateException("No CacheResolver specified, and no bean of type CacheManager found. " +
|
||||
|
|
@ -650,6 +649,9 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* A {@link CacheOperationInvocationContext} context for a {@link CacheOperation}.
|
||||
*/
|
||||
protected class CacheOperationContext implements CacheOperationInvocationContext<CacheOperation> {
|
||||
|
||||
private final CacheOperationMetadata metadata;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -100,7 +100,9 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B
|
|||
|
||||
/**
|
||||
* Specify the default task executor to use for asynchronous methods.
|
||||
* @deprecated as of 5.0.8, in favor of {@link #AsyncAnnotationAdvisor(Executor, AsyncUncaughtExceptionHandler)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setTaskExecutor(Executor executor) {
|
||||
this.advice = buildAdvice(executor, this.exceptionHandler);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -321,9 +321,8 @@ public abstract class AbstractBindingResult extends AbstractErrors implements Bi
|
|||
|
||||
@Override
|
||||
public String[] resolveMessageCodes(String errorCode, @Nullable String field) {
|
||||
Class<?> fieldType = (getTarget() != null ? getFieldType(field) : null);
|
||||
return getMessageCodesResolver().resolveMessageCodes(
|
||||
errorCode, getObjectName(), fixedField(field), fieldType);
|
||||
errorCode, getObjectName(), fixedField(field), getFieldType(field));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -332,7 +331,7 @@ public abstract class AbstractBindingResult extends AbstractErrors implements Bi
|
|||
}
|
||||
|
||||
@Override
|
||||
public void recordFieldValue(String field, Class<?> type, Object value) {
|
||||
public void recordFieldValue(String field, Class<?> type, @Nullable Object value) {
|
||||
this.fieldTypes.put(field, type);
|
||||
this.fieldValues.put(field, value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ public class BindException extends Exception implements BindingResult {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void recordFieldValue(String field, Class<?> type, Object value) {
|
||||
public void recordFieldValue(String field, Class<?> type, @Nullable Object value) {
|
||||
this.bindingResult.recordFieldValue(field, type, value);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ public interface BindingResult extends Errors {
|
|||
* @param value the original value
|
||||
* @since 5.0.4
|
||||
*/
|
||||
default void recordFieldValue(String field, Class<?> type, Object value) {
|
||||
default void recordFieldValue(String field, Class<?> type, @Nullable Object value) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -853,7 +853,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
|||
* @see #getBindingResult()
|
||||
*/
|
||||
public void validate() {
|
||||
for (Validator validator : this.validators) {
|
||||
for (Validator validator : getValidators()) {
|
||||
validator.validate(getTarget(), getBindingResult());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -66,23 +66,21 @@ public class EnableCachingTests extends AbstractCacheAnnotationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void singleCacheManagerBean() throws Throwable {
|
||||
public void singleCacheManagerBean() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(SingleCacheManagerConfig.class);
|
||||
ctx.refresh();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void multipleCacheManagerBeans() throws Throwable {
|
||||
@Test
|
||||
public void multipleCacheManagerBeans() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(MultiCacheManagerConfig.class);
|
||||
try {
|
||||
ctx.refresh();
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
Throwable root = ex.getRootCause();
|
||||
assertTrue(root.getMessage().contains("beans of type CacheManager"));
|
||||
throw root;
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().contains("no unique bean of type CacheManager"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,8 +91,8 @@ public class EnableCachingTests extends AbstractCacheAnnotationTests {
|
|||
ctx.refresh(); // does not throw an exception
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void multipleCachingConfigurers() throws Throwable {
|
||||
@Test
|
||||
public void multipleCachingConfigurers() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(MultiCacheManagerConfigurer.class, EnableCachingConfig.class);
|
||||
try {
|
||||
|
|
@ -102,22 +100,20 @@ public class EnableCachingTests extends AbstractCacheAnnotationTests {
|
|||
}
|
||||
catch (BeanCreationException ex) {
|
||||
Throwable root = ex.getRootCause();
|
||||
assertTrue(root instanceof IllegalStateException);
|
||||
assertTrue(root.getMessage().contains("implementations of CachingConfigurer"));
|
||||
throw root;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void noCacheManagerBeans() throws Throwable {
|
||||
@Test
|
||||
public void noCacheManagerBeans() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(EmptyConfig.class);
|
||||
try {
|
||||
ctx.refresh();
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
Throwable root = ex.getRootCause();
|
||||
assertTrue(root.getMessage().contains("No bean of type CacheManager"));
|
||||
throw root;
|
||||
catch (IllegalStateException ex) {
|
||||
assertTrue(ex.getMessage().contains("no bean of type CacheManager"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.springframework.core.convert.support;
|
|||
import java.util.Locale;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -35,6 +36,7 @@ import org.springframework.util.StringUtils;
|
|||
final class StringToLocaleConverter implements Converter<String, Locale> {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Locale convert(String source) {
|
||||
return StringUtils.parseLocale(source);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -651,9 +651,9 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
|
|||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private Reference<K, V>[] createReferenceArray(int size) {
|
||||
return (Reference<K, V>[]) Array.newInstance(Reference.class, size);
|
||||
return new Reference[size];
|
||||
}
|
||||
|
||||
private int getIndex(int hash, Reference<K, V>[] references) {
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ public class WebExchangeBindException extends ServerWebInputException implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public void recordFieldValue(String field, Class<?> type, Object value) {
|
||||
public void recordFieldValue(String field, Class<?> type, @Nullable Object value) {
|
||||
this.bindingResult.recordFieldValue(field, type, value);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import org.springframework.core.ParameterNameDiscoverer;
|
|||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.AbstractBindingResult;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
|
|
@ -289,13 +288,11 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
|
|||
}
|
||||
|
||||
if (bindingFailure) {
|
||||
if (binder.getBindingResult() instanceof AbstractBindingResult) {
|
||||
AbstractBindingResult result = (AbstractBindingResult) binder.getBindingResult();
|
||||
for (int i = 0; i < paramNames.length; i++) {
|
||||
result.recordFieldValue(paramNames[i], paramTypes[i], args[i]);
|
||||
}
|
||||
BindingResult result = binder.getBindingResult();
|
||||
for (int i = 0; i < paramNames.length; i++) {
|
||||
result.recordFieldValue(paramNames[i], paramTypes[i], args[i]);
|
||||
}
|
||||
throw new BindException(binder.getBindingResult());
|
||||
throw new BindException(result);
|
||||
}
|
||||
|
||||
return BeanUtils.instantiateClass(ctor, args);
|
||||
|
|
@ -319,13 +316,17 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
|
|||
* @param parameter the method parameter declaration
|
||||
*/
|
||||
protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {
|
||||
Annotation[] annotations = parameter.getParameterAnnotations();
|
||||
for (Annotation ann : annotations) {
|
||||
for (Annotation ann : parameter.getParameterAnnotations()) {
|
||||
Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
|
||||
if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
|
||||
Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
|
||||
Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
|
||||
binder.validate(validationHints);
|
||||
if (hints != null) {
|
||||
Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
|
||||
binder.validate(validationHints);
|
||||
}
|
||||
else {
|
||||
binder.validate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public class InMemoryWebSessionStore implements WebSessionStore {
|
|||
* {@link IllegalStateException}.
|
||||
* <p>By default set to 10000.
|
||||
* @param maxSessions the maximum number of sessions
|
||||
* @since 5.1
|
||||
* @since 5.0.8
|
||||
*/
|
||||
public void setMaxSessions(int maxSessions) {
|
||||
this.maxSessions = maxSessions;
|
||||
|
|
@ -70,7 +70,7 @@ public class InMemoryWebSessionStore implements WebSessionStore {
|
|||
|
||||
/**
|
||||
* Return the maximum number of sessions that can be stored.
|
||||
* @since 5.1
|
||||
* @since 5.0.8
|
||||
*/
|
||||
public int getMaxSessions() {
|
||||
return this.maxSessions;
|
||||
|
|
@ -102,9 +102,9 @@ public class InMemoryWebSessionStore implements WebSessionStore {
|
|||
* Return the map of sessions with an {@link Collections#unmodifiableMap
|
||||
* unmodifiable} wrapper. This could be used for management purposes, to
|
||||
* list active sessions, invalidate expired ones, etc.
|
||||
* @since 5.1
|
||||
* @since 5.0.8
|
||||
*/
|
||||
public Map<String, InMemoryWebSession> getSessions() {
|
||||
public Map<String, WebSession> getSessions() {
|
||||
return Collections.unmodifiableMap(this.sessions);
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ public class InMemoryWebSessionStore implements WebSessionStore {
|
|||
* kicked off lazily during calls to {@link #createWebSession() create} or
|
||||
* {@link #retrieveSession retrieve}, no less than 60 seconds apart.
|
||||
* This method can be called to force a check at a specific time.
|
||||
* @since 5.1
|
||||
* @since 5.0.8
|
||||
*/
|
||||
public void removeExpiredSessions() {
|
||||
this.expiredSessionChecker.removeExpiredSessions(this.clock.instant());
|
||||
|
|
|
|||
|
|
@ -255,7 +255,6 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||
// Encoding
|
||||
|
||||
HierarchicalUriComponents encodeTemplate(Charset charset) {
|
||||
|
||||
if (this.encodeState.isEncoded()) {
|
||||
return this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
|
|||
}
|
||||
|
||||
|
||||
// encode methods
|
||||
// Encode methods
|
||||
|
||||
/**
|
||||
* Request to have the URI template pre-encoded at build time, and
|
||||
|
|
@ -361,7 +361,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
|
|||
}
|
||||
|
||||
|
||||
// build methods
|
||||
// Build methods
|
||||
|
||||
/**
|
||||
* Build a {@code UriComponents} instance from the various components contained in this builder.
|
||||
|
|
@ -386,8 +386,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
|
|||
HierarchicalUriComponents uriComponents =
|
||||
new HierarchicalUriComponents(this.scheme, this.fragment, this.userInfo,
|
||||
this.host, this.port, this.pathBuilder.build(), this.queryParams, encoded);
|
||||
|
||||
return this.encodeTemplate ? uriComponents.encodeTemplate(this.charset) : uriComponents;
|
||||
return (this.encodeTemplate ? uriComponents.encodeTemplate(this.charset) : uriComponents);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -406,7 +405,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
|
|||
* Build a {@code UriComponents} instance and replaces URI template variables
|
||||
* with the values from an array. This is a shortcut method which combines
|
||||
* calls to {@link #build()} and then {@link UriComponents#expand(Object...)}.
|
||||
* @param uriVariableValues URI variable values
|
||||
* @param uriVariableValues the URI variable values
|
||||
* @return the URI components with expanded values
|
||||
*/
|
||||
public UriComponents buildAndExpand(Object... uriVariableValues) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -62,7 +62,7 @@ public class Jaxb2CollectionHttpMessageConverterTests {
|
|||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
public void setup() {
|
||||
converter = new Jaxb2CollectionHttpMessageConverter<Collection<Object>>();
|
||||
rootElementListType = new ParameterizedTypeReference<List<RootElement>>() {}.getType();
|
||||
rootElementSetType = new ParameterizedTypeReference<Set<RootElement>>() {}.getType();
|
||||
|
|
@ -72,7 +72,7 @@ public class Jaxb2CollectionHttpMessageConverterTests {
|
|||
|
||||
|
||||
@Test
|
||||
public void canRead() throws Exception {
|
||||
public void canRead() {
|
||||
assertTrue(converter.canRead(rootElementListType, null, null));
|
||||
assertTrue(converter.canRead(rootElementSetType, null, null));
|
||||
assertTrue(converter.canRead(typeSetType, null, null));
|
||||
|
|
@ -271,4 +271,4 @@ public class Jaxb2CollectionHttpMessageConverterTests {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -16,13 +16,7 @@
|
|||
|
||||
package org.springframework.http.converter.xml;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.xmlunit.diff.ComparisonType.*;
|
||||
import static org.xmlunit.diff.DifferenceEvaluators.*;
|
||||
import static org.xmlunit.matchers.CompareMatcher.*;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import javax.xml.bind.Marshaller;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
|
@ -48,6 +42,11 @@ import org.springframework.http.MockHttpInputMessage;
|
|||
import org.springframework.http.MockHttpOutputMessage;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.xmlunit.diff.ComparisonType.*;
|
||||
import static org.xmlunit.diff.DifferenceEvaluators.*;
|
||||
import static org.xmlunit.matchers.CompareMatcher.*;
|
||||
|
||||
/**
|
||||
* Tests for {@link Jaxb2RootElementHttpMessageConverter}.
|
||||
*
|
||||
|
|
@ -68,7 +67,7 @@ public class Jaxb2RootElementHttpMessageConverterTests {
|
|||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
public void setup() {
|
||||
converter = new Jaxb2RootElementHttpMessageConverter();
|
||||
rootElement = new RootElement();
|
||||
DefaultAopProxyFactory proxyFactory = new DefaultAopProxyFactory();
|
||||
|
|
@ -81,7 +80,7 @@ public class Jaxb2RootElementHttpMessageConverterTests {
|
|||
|
||||
|
||||
@Test
|
||||
public void canRead() throws Exception {
|
||||
public void canRead() {
|
||||
assertTrue("Converter does not support reading @XmlRootElement",
|
||||
converter.canRead(RootElement.class, null));
|
||||
assertTrue("Converter does not support reading @XmlType",
|
||||
|
|
@ -89,7 +88,7 @@ public class Jaxb2RootElementHttpMessageConverterTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void canWrite() throws Exception {
|
||||
public void canWrite() {
|
||||
assertTrue("Converter does not support writing @XmlRootElement",
|
||||
converter.canWrite(RootElement.class, null));
|
||||
assertTrue("Converter does not support writing @XmlRootElement subclass",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
|
|
@ -43,7 +43,7 @@ import static org.mockito.BDDMockito.*;
|
|||
public class MarshallingHttpMessageConverterTests {
|
||||
|
||||
@Test
|
||||
public void canRead() throws Exception {
|
||||
public void canRead() {
|
||||
Unmarshaller unmarshaller = mock(Unmarshaller.class);
|
||||
|
||||
given(unmarshaller.supports(Integer.class)).willReturn(false);
|
||||
|
|
@ -58,7 +58,7 @@ public class MarshallingHttpMessageConverterTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void canWrite() throws Exception {
|
||||
public void canWrite() {
|
||||
Marshaller marshaller = mock(Marshaller.class);
|
||||
|
||||
given(marshaller.supports(Integer.class)).willReturn(false);
|
||||
|
|
@ -130,8 +130,8 @@ public class MarshallingHttpMessageConverterTests {
|
|||
MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(marshaller);
|
||||
converter.write(body, null, outputMessage);
|
||||
|
||||
assertEquals("Invalid content-type", new MediaType("application", "xml"), outputMessage.getHeaders()
|
||||
.getContentType());
|
||||
assertEquals("Invalid content-type", new MediaType("application", "xml"),
|
||||
outputMessage.getHeaders().getContentType());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -48,13 +48,8 @@ import org.springframework.http.MockHttpOutputMessage;
|
|||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.xmlunit.matchers.CompareMatcher.isSimilarTo;
|
||||
|
||||
// Do NOT statically import org.junit.Assert.*, since XMLAssert extends junit.framework.Assert
|
||||
import static org.junit.Assert.*;
|
||||
import static org.xmlunit.matchers.CompareMatcher.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -73,7 +68,7 @@ public class SourceHttpMessageConverterTests {
|
|||
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
public void setup() throws IOException {
|
||||
converter = new SourceHttpMessageConverter<>();
|
||||
Resource external = new ClassPathResource("external.txt", getClass());
|
||||
|
||||
|
|
@ -163,7 +158,7 @@ public class SourceHttpMessageConverterTests {
|
|||
XMLReader reader = result.getXMLReader();
|
||||
reader.setContentHandler(new DefaultHandler() {
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
public void characters(char[] ch, int start, int length) {
|
||||
String s = new String(ch, start, length);
|
||||
assertNotEquals("Invalid result", "Foo Bar", s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
|||
valueType = getReturnValueType(outputValue, returnType);
|
||||
declaredType = getGenericType(returnType);
|
||||
}
|
||||
|
||||
|
||||
if (isResourceType(value, returnType)) {
|
||||
outputMessage.getHeaders().set(HttpHeaders.ACCEPT_RANGES, "bytes");
|
||||
if (value != null && inputMessage.getHeaders().getFirst(HttpHeaders.RANGE) != null) {
|
||||
|
|
@ -258,12 +258,12 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
|||
if (selectedMediaType != null) {
|
||||
selectedMediaType = selectedMediaType.removeQualityValue();
|
||||
for (HttpMessageConverter<?> converter : this.messageConverters) {
|
||||
GenericHttpMessageConverter genericConverter =
|
||||
(converter instanceof GenericHttpMessageConverter ? (GenericHttpMessageConverter<?>) converter : null);
|
||||
GenericHttpMessageConverter genericConverter = (converter instanceof GenericHttpMessageConverter ?
|
||||
(GenericHttpMessageConverter<?>) converter : null);
|
||||
if (genericConverter != null ?
|
||||
((GenericHttpMessageConverter) converter).canWrite(declaredType, valueType, selectedMediaType) :
|
||||
converter.canWrite(valueType, selectedMediaType)) {
|
||||
outputValue = (T) getAdvice().beforeBodyWrite(outputValue, returnType, selectedMediaType,
|
||||
outputValue = getAdvice().beforeBodyWrite(outputValue, returnType, selectedMediaType,
|
||||
(Class<? extends HttpMessageConverter<?>>) converter.getClass(),
|
||||
inputMessage, outputMessage);
|
||||
if (outputValue != null) {
|
||||
|
|
@ -300,7 +300,7 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
|||
}
|
||||
|
||||
/**
|
||||
* Return whether the returned value or the declared return type extend {@link Resource}
|
||||
* Return whether the returned value or the declared return type extends {@link Resource}.
|
||||
*/
|
||||
protected boolean isResourceType(@Nullable Object value, MethodParameter returnType) {
|
||||
Class<?> clazz = getReturnValueType(value, returnType);
|
||||
|
|
@ -321,15 +321,16 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the media types that can be produced.
|
||||
* @see #getProducibleMediaTypes(HttpServletRequest, Class, Type)
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "unused"})
|
||||
@SuppressWarnings("unused")
|
||||
protected List<MediaType> getProducibleMediaTypes(HttpServletRequest request, Class<?> valueClass) {
|
||||
return getProducibleMediaTypes(request, valueClass, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the media types that can be produced:
|
||||
* Returns the media types that can be produced. The resulting media types are:
|
||||
* <ul>
|
||||
* <li>The producible media types specified in the request mappings, or
|
||||
* <li>Media types of configured converters that can write the specific return value, or
|
||||
|
|
@ -338,10 +339,11 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
|||
* @since 4.2
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<MediaType> getProducibleMediaTypes(HttpServletRequest request, Class<?> valueClass,
|
||||
@Nullable Type declaredType) {
|
||||
protected List<MediaType> getProducibleMediaTypes(
|
||||
HttpServletRequest request, Class<?> valueClass, @Nullable Type declaredType) {
|
||||
|
||||
Set<MediaType> mediaTypes = (Set<MediaType>) request.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
|
||||
Set<MediaType> mediaTypes =
|
||||
(Set<MediaType>) request.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
|
||||
if (!CollectionUtils.isEmpty(mediaTypes)) {
|
||||
return new ArrayList<>(mediaTypes);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
|
@ -86,13 +85,7 @@ import org.springframework.web.servlet.HandlerMapping;
|
|||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* A test fixture with a controller with all supported method signature styles
|
||||
|
|
@ -378,7 +371,7 @@ public class RequestMappingHandlerAdapterIntegrationTests {
|
|||
User user,
|
||||
@ModelAttribute OtherUser otherUser,
|
||||
Model model,
|
||||
UriComponentsBuilder builder) throws Exception {
|
||||
UriComponentsBuilder builder) {
|
||||
|
||||
model.addAttribute("cookie", cookie).addAttribute("pathvar", pathvar).addAttribute("header", header)
|
||||
.addAttribute("systemHeader", systemHeader).addAttribute("headerMap", headerMap)
|
||||
|
|
@ -404,7 +397,7 @@ public class RequestMappingHandlerAdapterIntegrationTests {
|
|||
|
||||
@ResponseStatus(code = HttpStatus.ACCEPTED)
|
||||
@ResponseBody
|
||||
public String handleAndValidateRequestBody(@Valid TestBean modelAttr, Errors errors) throws Exception {
|
||||
public String handleAndValidateRequestBody(@Valid TestBean modelAttr, Errors errors) {
|
||||
return "Error count [" + errors.getErrorCount() + "]";
|
||||
}
|
||||
|
||||
|
|
@ -453,7 +446,7 @@ public class RequestMappingHandlerAdapterIntegrationTests {
|
|||
private static class ColorArgumentResolver implements WebArgumentResolver {
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception {
|
||||
public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) {
|
||||
return new Color(0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -54,8 +54,7 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
import org.springframework.web.servlet.FlashMap;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link RequestMappingHandlerAdapter}.
|
||||
|
|
@ -257,7 +256,6 @@ public class RequestMappingHandlerAdapterTests {
|
|||
|
||||
@Test
|
||||
public void jsonpResponseBodyAdvice() throws Exception {
|
||||
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
||||
converters.add(new MappingJackson2HttpMessageConverter());
|
||||
this.handlerAdapter.setMessageConverters(converters);
|
||||
|
|
|
|||
Loading…
Reference in New Issue