提交 bfba53f9 编写于 作者: J Juergen Hoeller

Fixed handling of primitive vararg array in CacheOperationContext

Issue: SPR-11249
上级 cb682cd8
......@@ -25,6 +25,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.cache.Cache;
......@@ -37,6 +38,7 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
......@@ -114,7 +116,7 @@ public abstract class CacheAspectSupport implements InitializingBean {
/**
* Set the KeyGenerator for this cache aspect.
* Default is {@link DefaultKeyGenerator}.
* The default is a {@link SimpleKeyGenerator}.
*/
public void setKeyGenerator(KeyGenerator keyGenerator) {
this.keyGenerator = keyGenerator;
......@@ -249,8 +251,8 @@ public abstract class CacheAspectSupport implements InitializingBean {
}
private void logInvalidating(CacheOperationContext context, CacheEvictOperation operation, Object key) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Invalidating " + (key == null ? "entire cache" : "cache key " + key) +
if (logger.isTraceEnabled()) {
logger.trace("Invalidating " + (key != null ? "cache key [" + key + "]" : "entire cache") +
" for operation " + operation + " on method " + context.method);
}
}
......@@ -302,8 +304,8 @@ public abstract class CacheAspectSupport implements InitializingBean {
private boolean isConditionPassing(CacheOperationContext context, Object result) {
boolean passing = context.isConditionPassing(result);
if (!passing && this.logger.isTraceEnabled()) {
this.logger.trace("Cache condition failed on method " + context.method + " for operation " + context.operation);
if (!passing && logger.isTraceEnabled()) {
logger.trace("Cache condition failed on method " + context.method + " for operation " + context.operation);
}
return passing;
}
......@@ -312,8 +314,8 @@ public abstract class CacheAspectSupport implements InitializingBean {
Object key = context.generateKey(result);
Assert.notNull(key, "Null key returned for cache operation (maybe you are using named params " +
"on classes without debug info?) " + context.operation);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Computed cache key " + key + " for operation " + context.operation);
if (logger.isTraceEnabled()) {
logger.trace("Computed cache key " + key + " for operation " + context.operation);
}
return key;
}
......@@ -334,7 +336,7 @@ public abstract class CacheAspectSupport implements InitializingBean {
Method method, Object[] args, Object target, Class<?> targetClass) {
for (CacheOperation operation : operations) {
this.contexts.add(operation.getClass(), new CacheOperationContext(operation, method, args, target, targetClass));
this.contexts.add(operation.getClass(), getOperationContext(operation, method, args, target, targetClass));
}
}
......@@ -373,7 +375,7 @@ public abstract class CacheAspectSupport implements InitializingBean {
if (!method.isVarArgs()) {
return args;
}
Object[] varArgs = (Object[]) args[args.length - 1];
Object[] varArgs = ObjectUtils.toObjectArray(args[args.length - 1]);
Object[] combinedArgs = new Object[args.length - 1 + varArgs.length];
System.arraycopy(args, 0, combinedArgs, 0, args.length - 1);
System.arraycopy(varArgs, 0, combinedArgs, args.length - 1, varArgs.length);
......@@ -416,7 +418,8 @@ public abstract class CacheAspectSupport implements InitializingBean {
}
private EvaluationContext createEvaluationContext(Object result) {
return evaluator.createEvaluationContext(this.caches, this.method, this.args, this.target, this.targetClass, result);
return evaluator.createEvaluationContext(
this.caches, this.method, this.args, this.target, this.targetClass, result);
}
protected Collection<? extends Cache> getCaches() {
......
......@@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.cache.annotation.EnableCaching;
......@@ -34,13 +35,13 @@ import static org.junit.Assert.*;
* Tests to reproduce raised caching issues.
*
* @author Phillip Webb
* @author Juergen Hoeller
*/
public class CacheReproTests {
@Test
public void spr11124() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
Spr11124Config.class);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr11124Config.class);
Spr11124Service bean = context.getBean(Spr11124Service.class);
bean.single(2);
bean.single(2);
......@@ -49,6 +50,16 @@ public class CacheReproTests {
context.close();
}
@Test
public void spr11249() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr11249Config.class);
Spr11249Service bean = context.getBean(Spr11249Service.class);
Object result = bean.doSomething("op", 2, 3);
assertSame(result, bean.doSomething("op", 2, 3));
context.close();
}
@Configuration
@EnableCaching
public static class Spr11124Config {
......@@ -62,23 +73,23 @@ public class CacheReproTests {
public Spr11124Service service() {
return new Spr11124ServiceImpl();
}
}
public interface Spr11124Service {
public List<String> single(int id);
public List<String> multiple(int id);
}
public static class Spr11124ServiceImpl implements Spr11124Service {
private int multipleCount = 0;
@Override
@Cacheable(value = "smallCache")
@Cacheable("smallCache")
public List<String> single(int id) {
if (this.multipleCount > 0) {
fail("Called too many times");
......@@ -98,7 +109,31 @@ public class CacheReproTests {
this.multipleCount++;
return Collections.emptyList();
}
}
@Configuration
@EnableCaching
public static class Spr11249Config {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
@Bean
public Spr11249Service service() {
return new Spr11249Service();
}
}
public static class Spr11249Service {
@Cacheable("smallCache")
public Object doSomething(String name, int... values) {
return new Object();
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册