Merge pull request #22769 from lgxbslgx
* pr/22769: Polish "Evaluate key only if necessary" Evaluate key only if necessary Closes gh-22769
This commit is contained in:
commit
d61b9c6294
|
@ -401,13 +401,6 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||||
// Check if we have a cached item matching the conditions
|
// Check if we have a cached item matching the conditions
|
||||||
Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
|
Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
|
||||||
|
|
||||||
// Collect puts from any @Cacheable miss, if no cached item is found
|
|
||||||
List<CachePutRequest> cachePutRequests = new ArrayList<>();
|
|
||||||
if (cacheHit == null) {
|
|
||||||
collectPutRequests(contexts.get(CacheableOperation.class),
|
|
||||||
CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object cacheValue;
|
Object cacheValue;
|
||||||
Object returnValue;
|
Object returnValue;
|
||||||
|
|
||||||
|
@ -422,6 +415,12 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||||
cacheValue = unwrapReturnValue(returnValue);
|
cacheValue = unwrapReturnValue(returnValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Collect puts from any @Cacheable miss, if no cached item is found
|
||||||
|
List<CachePutRequest> cachePutRequests = new ArrayList<>();
|
||||||
|
if (cacheHit == null) {
|
||||||
|
collectPutRequests(contexts.get(CacheableOperation.class), cacheValue, cachePutRequests);
|
||||||
|
}
|
||||||
|
|
||||||
// Collect any explicit @CachePuts
|
// Collect any explicit @CachePuts
|
||||||
collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);
|
collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);
|
||||||
|
|
||||||
|
@ -558,7 +557,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||||
@Nullable Object result, Collection<CachePutRequest> putRequests) {
|
@Nullable Object result, Collection<CachePutRequest> putRequests) {
|
||||||
|
|
||||||
for (CacheOperationContext context : contexts) {
|
for (CacheOperationContext context : contexts) {
|
||||||
if (isConditionPassing(context, result)) {
|
if (isConditionPassing(context, result) && context.canPutToCache(result)) {
|
||||||
Object key = generateKey(context, result);
|
Object key = generateKey(context, result);
|
||||||
putRequests.add(new CachePutRequest(context, key));
|
putRequests.add(new CachePutRequest(context, key));
|
||||||
}
|
}
|
||||||
|
@ -832,13 +831,11 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply(@Nullable Object result) {
|
public void apply(@Nullable Object result) {
|
||||||
if (this.context.canPutToCache(result)) {
|
|
||||||
for (Cache cache : this.context.getCaches()) {
|
for (Cache cache : this.context.getCaches()) {
|
||||||
doPut(cache, this.key, result);
|
doPut(cache, this.key, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static final class CacheOperationCacheKey implements Comparable<CacheOperationCacheKey> {
|
private static final class CacheOperationCacheKey implements Comparable<CacheOperationCacheKey> {
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
<cache:cache-put method="multiUpdate" cache="primary"/>
|
<cache:cache-put method="multiUpdate" cache="primary"/>
|
||||||
<cache:cache-put method="multiUpdate" cache="secondary"/>
|
<cache:cache-put method="multiUpdate" cache="secondary"/>
|
||||||
<cache:cache-put method="putRefersToResult" cache="primary" key="#result.id"/>
|
<cache:cache-put method="putRefersToResult" cache="primary" key="#result.id"/>
|
||||||
|
<cache:cache-put method="putEvaluatesUnlessBeforeKey" cache="primary" key="#result.id" unless="#result == null"/>
|
||||||
</cache:caching>
|
</cache:caching>
|
||||||
</cache:advice>
|
</cache:advice>
|
||||||
|
|
||||||
|
@ -93,6 +94,7 @@
|
||||||
<cache:cache-put method="multiUpdate" cache="primary"/>
|
<cache:cache-put method="multiUpdate" cache="primary"/>
|
||||||
<cache:cache-put method="multiUpdate" cache="secondary"/>
|
<cache:cache-put method="multiUpdate" cache="secondary"/>
|
||||||
<cache:cache-put method="putRefersToResult" cache="primary" key="#result.id"/>
|
<cache:cache-put method="putRefersToResult" cache="primary" key="#result.id"/>
|
||||||
|
<cache:cache-put method="putEvaluatesUnlessBeforeKey" cache="primary" key="#result.id" unless="#result == null"/>
|
||||||
</cache:caching>
|
</cache:caching>
|
||||||
</cache:advice>
|
</cache:advice>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -504,6 +504,26 @@ public abstract class AbstractCacheAnnotationTests {
|
||||||
assertThat(primary.get(id).get()).isSameAs(entity);
|
assertThat(primary.get(id).get()).isSameAs(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void testPutRefersToResultWithUnless(CacheableService<?> service) {
|
||||||
|
Long id = 42L;
|
||||||
|
TestEntity entity = new TestEntity();
|
||||||
|
entity.setId(id);
|
||||||
|
Cache primary = this.cm.getCache("primary");
|
||||||
|
assertThat(primary.get(id)).isNull();
|
||||||
|
assertThat(service.putEvaluatesUnlessBeforeKey(entity)).isNotNull();
|
||||||
|
assertThat(primary.get(id).get()).isSameAs(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void testPutEvaluatesUnlessBeforeKey(CacheableService<?> service) {
|
||||||
|
Long id = Long.MIN_VALUE; // return null
|
||||||
|
TestEntity entity = new TestEntity();
|
||||||
|
entity.setId(id);
|
||||||
|
Cache primary = this.cm.getCache("primary");
|
||||||
|
assertThat(primary.get(id)).isNull();
|
||||||
|
assertThat(service.putEvaluatesUnlessBeforeKey(entity)).isNull();
|
||||||
|
assertThat(primary.get(id)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
protected void testMultiCacheAndEvict(CacheableService<?> service) {
|
protected void testMultiCacheAndEvict(CacheableService<?> service) {
|
||||||
String methodName = "multiCacheAndEvict";
|
String methodName = "multiCacheAndEvict";
|
||||||
|
|
||||||
|
@ -849,11 +869,31 @@ public abstract class AbstractCacheAnnotationTests {
|
||||||
testPutRefersToResult(this.cs);
|
testPutRefersToResult(this.cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPutRefersToResultWithUnless() {
|
||||||
|
testPutRefersToResultWithUnless(this.cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPutEvaluatesUnlessBeforeKey() {
|
||||||
|
testPutEvaluatesUnlessBeforeKey(this.cs);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClassPutRefersToResult() {
|
public void testClassPutRefersToResult() {
|
||||||
testPutRefersToResult(this.ccs);
|
testPutRefersToResult(this.ccs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassPutRefersToResultWithUnless(){
|
||||||
|
testPutRefersToResultWithUnless(this.ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassPutEvaluatesUnlessBeforeKey(){
|
||||||
|
testPutEvaluatesUnlessBeforeKey(this.ccs);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMultiCacheAndEvict() {
|
public void testMultiCacheAndEvict() {
|
||||||
testMultiCacheAndEvict(this.cs);
|
testMultiCacheAndEvict(this.cs);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -235,4 +235,10 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
|
||||||
return arg1;
|
return arg1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@CachePut(cacheNames = "primary", key = "#result.id", unless = "#result == null")
|
||||||
|
public TestEntity putEvaluatesUnlessBeforeKey(TestEntity arg1) {
|
||||||
|
return (arg1.getId() != Long.MIN_VALUE ? arg1 : null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -93,4 +93,6 @@ public interface CacheableService<T> {
|
||||||
|
|
||||||
TestEntity putRefersToResult(TestEntity arg1);
|
TestEntity putRefersToResult(TestEntity arg1);
|
||||||
|
|
||||||
|
TestEntity putEvaluatesUnlessBeforeKey(TestEntity arg1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -243,4 +243,10 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
||||||
return arg1;
|
return arg1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@CachePut(cacheNames = "primary", key = "#result.id", unless = "#result == null")
|
||||||
|
public TestEntity putEvaluatesUnlessBeforeKey(TestEntity arg1) {
|
||||||
|
return (arg1.getId() != Long.MIN_VALUE ? arg1 : null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue