+ update aspectj cache aspects
+ update integration tests
This commit is contained in:
parent
1e2f49104d
commit
d10f2258e8
|
@ -18,7 +18,9 @@ package org.springframework.cache.aspectj;
|
||||||
|
|
||||||
import org.springframework.cache.annotation.AnnotationCacheOperationSource;
|
import org.springframework.cache.annotation.AnnotationCacheOperationSource;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
|
import org.springframework.cache.annotation.CachePut;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
|
import org.springframework.cache.annotation.Caching;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete AspectJ cache aspect using Spring's @{@link Cacheable} annotation.
|
* Concrete AspectJ cache aspect using Spring's @{@link Cacheable} annotation.
|
||||||
|
@ -59,6 +61,20 @@ public aspect AnnotationCacheAspect extends AbstractCacheAspect {
|
||||||
private pointcut executionOfAnyPublicMethodInAtCacheEvictType() :
|
private pointcut executionOfAnyPublicMethodInAtCacheEvictType() :
|
||||||
execution(public * ((@CacheEvict *)+).*(..)) && @this(CacheEvict);
|
execution(public * ((@CacheEvict *)+).*(..)) && @this(CacheEvict);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches the execution of any public method in a type with the @{@link CachePut}
|
||||||
|
* annotation, or any subtype of a type with the {@code CachePut} annotation.
|
||||||
|
*/
|
||||||
|
private pointcut executionOfAnyPublicMethodInAtCachePutType() :
|
||||||
|
execution(public * ((@CachePut *)+).*(..)) && @this(CachePut);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches the execution of any public method in a type with the @{@link Caching}
|
||||||
|
* annotation, or any subtype of a type with the {@code Caching} annotation.
|
||||||
|
*/
|
||||||
|
private pointcut executionOfAnyPublicMethodInAtCachingType() :
|
||||||
|
execution(public * ((@Caching *)+).*(..)) && @this(Caching);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any method with the @{@link Cacheable} annotation.
|
* Matches the execution of any method with the @{@link Cacheable} annotation.
|
||||||
*/
|
*/
|
||||||
|
@ -71,6 +87,18 @@ public aspect AnnotationCacheAspect extends AbstractCacheAspect {
|
||||||
private pointcut executionOfCacheEvictMethod() :
|
private pointcut executionOfCacheEvictMethod() :
|
||||||
execution(* *(..)) && @annotation(CacheEvict);
|
execution(* *(..)) && @annotation(CacheEvict);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches the execution of any method with the @{@link CachePut} annotation.
|
||||||
|
*/
|
||||||
|
private pointcut executionOfCachePutMethod() :
|
||||||
|
execution(* *(..)) && @annotation(CachePut);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches the execution of any method with the @{@link Caching} annotation.
|
||||||
|
*/
|
||||||
|
private pointcut executionOfCachingMethod() :
|
||||||
|
execution(* *(..)) && @annotation(Caching);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of pointcut from super aspect - matched join points will have Spring
|
* Definition of pointcut from super aspect - matched join points will have Spring
|
||||||
* cache management applied.
|
* cache management applied.
|
||||||
|
@ -78,8 +106,11 @@ public aspect AnnotationCacheAspect extends AbstractCacheAspect {
|
||||||
protected pointcut cacheMethodExecution(Object cachedObject) :
|
protected pointcut cacheMethodExecution(Object cachedObject) :
|
||||||
(executionOfAnyPublicMethodInAtCacheableType()
|
(executionOfAnyPublicMethodInAtCacheableType()
|
||||||
|| executionOfAnyPublicMethodInAtCacheEvictType()
|
|| executionOfAnyPublicMethodInAtCacheEvictType()
|
||||||
|
|| executionOfAnyPublicMethodInAtCachePutType()
|
||||||
|
|| executionOfAnyPublicMethodInAtCachingType()
|
||||||
|| executionOfCacheableMethod()
|
|| executionOfCacheableMethod()
|
||||||
|| executionOfCacheEvictMethod())
|
|| executionOfCacheEvictMethod()
|
||||||
|
|| executionOfCachePutMethod()
|
||||||
|
|| executionOfCachingMethod())
|
||||||
&& this(cachedObject);
|
&& this(cachedObject);
|
||||||
|
}
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2010 the original author or authors.
|
* Copyright 2010-2011 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.
|
||||||
|
@ -18,38 +18,48 @@ package org.springframework.cache.aspectj;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.cache.Cache;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.config.AnnotatedClassCacheableService;
|
||||||
import org.springframework.cache.config.CacheableService;
|
import org.springframework.cache.config.CacheableService;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract annotation test (containing several reusable methods).
|
* Abstract annotation test (containing several reusable methods).
|
||||||
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
|
* @author Chris Beams
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractAnnotationTest {
|
public abstract class AbstractAnnotationTest {
|
||||||
|
|
||||||
protected ApplicationContext ctx;
|
protected ApplicationContext ctx;
|
||||||
|
|
||||||
protected CacheableService cs;
|
protected CacheableService<?> cs;
|
||||||
|
|
||||||
protected CacheableService ccs;
|
protected CacheableService<?> ccs;
|
||||||
|
|
||||||
protected abstract String getConfig();
|
protected CacheManager cm;
|
||||||
|
|
||||||
|
/** @return a refreshed application context */
|
||||||
|
protected abstract ApplicationContext getApplicationContext();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
ctx = new ClassPathXmlApplicationContext(getConfig());
|
ctx = getApplicationContext();
|
||||||
cs = ctx.getBean("service", CacheableService.class);
|
cs = ctx.getBean("service", CacheableService.class);
|
||||||
ccs = ctx.getBean("classService", CacheableService.class);
|
ccs = ctx.getBean("classService", CacheableService.class);
|
||||||
|
cm = ctx.getBean(CacheManager.class);
|
||||||
|
Collection<String> cn = cm.getCacheNames();
|
||||||
|
assertTrue(cn.contains("default"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCacheable(CacheableService service) throws Exception {
|
public void testCacheable(CacheableService<?> service) throws Exception {
|
||||||
Object o1 = new Object();
|
Object o1 = new Object();
|
||||||
Object o2 = new Object();
|
|
||||||
|
|
||||||
Object r1 = service.cache(o1);
|
Object r1 = service.cache(o1);
|
||||||
Object r2 = service.cache(o1);
|
Object r2 = service.cache(o1);
|
||||||
|
@ -59,9 +69,8 @@ public abstract class AbstractAnnotationTest {
|
||||||
assertSame(r1, r3);
|
assertSame(r1, r3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInvalidate(CacheableService service) throws Exception {
|
public void testEvict(CacheableService<?> service) throws Exception {
|
||||||
Object o1 = new Object();
|
Object o1 = new Object();
|
||||||
Object o2 = new Object();
|
|
||||||
|
|
||||||
Object r1 = service.cache(o1);
|
Object r1 = service.cache(o1);
|
||||||
Object r2 = service.cache(o1);
|
Object r2 = service.cache(o1);
|
||||||
|
@ -74,7 +83,98 @@ public abstract class AbstractAnnotationTest {
|
||||||
assertSame(r3, r4);
|
assertSame(r3, r4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConditionalExpression(CacheableService service) throws Exception {
|
public void testEvictEarly(CacheableService<?> service) throws Exception {
|
||||||
|
Object o1 = new Object();
|
||||||
|
|
||||||
|
Object r1 = service.cache(o1);
|
||||||
|
Object r2 = service.cache(o1);
|
||||||
|
|
||||||
|
assertSame(r1, r2);
|
||||||
|
try {
|
||||||
|
service.evictEarly(o1);
|
||||||
|
} catch (RuntimeException ex) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
Object r3 = service.cache(o1);
|
||||||
|
Object r4 = service.cache(o1);
|
||||||
|
assertNotSame(r1, r3);
|
||||||
|
assertSame(r3, r4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEvictException(CacheableService<?> service) throws Exception {
|
||||||
|
Object o1 = new Object();
|
||||||
|
|
||||||
|
Object r1 = service.cache(o1);
|
||||||
|
Object r2 = service.cache(o1);
|
||||||
|
|
||||||
|
assertSame(r1, r2);
|
||||||
|
try {
|
||||||
|
service.evictWithException(o1);
|
||||||
|
} catch (RuntimeException ex) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
// exception occurred, eviction skipped, data should still be in the cache
|
||||||
|
Object r3 = service.cache(o1);
|
||||||
|
assertSame(r1, r3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEvictWKey(CacheableService<?> service) throws Exception {
|
||||||
|
Object o1 = new Object();
|
||||||
|
|
||||||
|
Object r1 = service.cache(o1);
|
||||||
|
Object r2 = service.cache(o1);
|
||||||
|
|
||||||
|
assertSame(r1, r2);
|
||||||
|
service.evict(o1, null);
|
||||||
|
Object r3 = service.cache(o1);
|
||||||
|
Object r4 = service.cache(o1);
|
||||||
|
assertNotSame(r1, r3);
|
||||||
|
assertSame(r3, r4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEvictWKeyEarly(CacheableService<?> service) throws Exception {
|
||||||
|
Object o1 = new Object();
|
||||||
|
|
||||||
|
Object r1 = service.cache(o1);
|
||||||
|
Object r2 = service.cache(o1);
|
||||||
|
|
||||||
|
assertSame(r1, r2);
|
||||||
|
|
||||||
|
try {
|
||||||
|
service.invalidateEarly(o1, null);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
Object r3 = service.cache(o1);
|
||||||
|
Object r4 = service.cache(o1);
|
||||||
|
assertNotSame(r1, r3);
|
||||||
|
assertSame(r3, r4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEvictAll(CacheableService<?> service) throws Exception {
|
||||||
|
Object o1 = new Object();
|
||||||
|
|
||||||
|
Object r1 = service.cache(o1);
|
||||||
|
Object r2 = service.cache(o1);
|
||||||
|
|
||||||
|
Object o2 = new Object();
|
||||||
|
Object r10 = service.cache(o2);
|
||||||
|
|
||||||
|
assertSame(r1, r2);
|
||||||
|
assertNotSame(r1, r10);
|
||||||
|
service.evictAll(new Object());
|
||||||
|
Cache cache = cm.getCache("default");
|
||||||
|
assertNull(cache.get(o1));
|
||||||
|
assertNull(cache.get(o2));
|
||||||
|
|
||||||
|
Object r3 = service.cache(o1);
|
||||||
|
Object r4 = service.cache(o1);
|
||||||
|
assertNotSame(r1, r3);
|
||||||
|
assertSame(r3, r4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testConditionalExpression(CacheableService<?> service) throws Exception {
|
||||||
Object r1 = service.conditional(4);
|
Object r1 = service.conditional(4);
|
||||||
Object r2 = service.conditional(4);
|
Object r2 = service.conditional(4);
|
||||||
|
|
||||||
|
@ -86,7 +186,7 @@ public abstract class AbstractAnnotationTest {
|
||||||
assertSame(r3, r4);
|
assertSame(r3, r4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKeyExpression(CacheableService service) throws Exception {
|
public void testKeyExpression(CacheableService<?> service) throws Exception {
|
||||||
Object r1 = service.key(5, 1);
|
Object r1 = service.key(5, 1);
|
||||||
Object r2 = service.key(5, 2);
|
Object r2 = service.key(5, 2);
|
||||||
|
|
||||||
|
@ -98,7 +198,26 @@ public abstract class AbstractAnnotationTest {
|
||||||
assertNotSame(r3, r4);
|
assertNotSame(r3, r4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCheckedThrowable(CacheableService service) throws Exception {
|
public void testNullValue(CacheableService<?> service) throws Exception {
|
||||||
|
Object key = new Object();
|
||||||
|
assertNull(service.nullValue(key));
|
||||||
|
int nr = service.nullInvocations().intValue();
|
||||||
|
assertNull(service.nullValue(key));
|
||||||
|
assertEquals(nr, service.nullInvocations().intValue());
|
||||||
|
assertNull(service.nullValue(new Object()));
|
||||||
|
assertEquals(nr + 1, service.nullInvocations().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMethodName(CacheableService<?> service, String keyName) throws Exception {
|
||||||
|
Object key = new Object();
|
||||||
|
Object r1 = service.name(key);
|
||||||
|
assertSame(r1, service.name(key));
|
||||||
|
Cache cache = cm.getCache("default");
|
||||||
|
// assert the method name is used
|
||||||
|
assertNotNull(cache.get(keyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCheckedThrowable(CacheableService<?> service) throws Exception {
|
||||||
String arg = UUID.randomUUID().toString();
|
String arg = UUID.randomUUID().toString();
|
||||||
try {
|
try {
|
||||||
service.throwChecked(arg);
|
service.throwChecked(arg);
|
||||||
|
@ -108,16 +227,165 @@ public abstract class AbstractAnnotationTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUncheckedThrowable(CacheableService service) throws Exception {
|
public void testUncheckedThrowable(CacheableService<?> service) throws Exception {
|
||||||
try {
|
try {
|
||||||
service.throwUnchecked(Long.valueOf(1));
|
service.throwUnchecked(Long.valueOf(1));
|
||||||
fail("Excepted exception");
|
fail("Excepted exception");
|
||||||
} catch (RuntimeException ex) {
|
} catch (RuntimeException ex) {
|
||||||
assertTrue(ex instanceof UnsupportedOperationException);
|
assertTrue("Excepted different exception type and got " + ex.getClass(),
|
||||||
|
ex instanceof UnsupportedOperationException);
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testNullArg(CacheableService<?> service) {
|
||||||
|
Object r1 = service.cache(null);
|
||||||
|
assertSame(r1, service.cache(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCacheUpdate(CacheableService<?> service) {
|
||||||
|
Object o = new Object();
|
||||||
|
Cache cache = cm.getCache("default");
|
||||||
|
assertNull(cache.get(o));
|
||||||
|
Object r1 = service.update(o);
|
||||||
|
assertSame(r1, cache.get(o).get());
|
||||||
|
|
||||||
|
o = new Object();
|
||||||
|
assertNull(cache.get(o));
|
||||||
|
Object r2 = service.update(o);
|
||||||
|
assertSame(r2, cache.get(o).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testConditionalCacheUpdate(CacheableService<?> service) {
|
||||||
|
Integer one = Integer.valueOf(1);
|
||||||
|
Integer three = Integer.valueOf(3);
|
||||||
|
|
||||||
|
Cache cache = cm.getCache("default");
|
||||||
|
assertEquals(one, Integer.valueOf(service.conditionalUpdate(one).toString()));
|
||||||
|
assertNull(cache.get(one));
|
||||||
|
|
||||||
|
assertEquals(three, Integer.valueOf(service.conditionalUpdate(three).toString()));
|
||||||
|
assertEquals(three, Integer.valueOf(cache.get(three).get().toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMultiCache(CacheableService<?> service) {
|
||||||
|
Object o1 = new Object();
|
||||||
|
Object o2 = new Object();
|
||||||
|
|
||||||
|
Cache primary = cm.getCache("primary");
|
||||||
|
Cache secondary = cm.getCache("secondary");
|
||||||
|
|
||||||
|
assertNull(primary.get(o1));
|
||||||
|
assertNull(secondary.get(o1));
|
||||||
|
Object r1 = service.multiCache(o1);
|
||||||
|
assertSame(r1, primary.get(o1).get());
|
||||||
|
assertSame(r1, secondary.get(o1).get());
|
||||||
|
|
||||||
|
Object r2 = service.multiCache(o1);
|
||||||
|
Object r3 = service.multiCache(o1);
|
||||||
|
|
||||||
|
assertSame(r1, r2);
|
||||||
|
assertSame(r1, r3);
|
||||||
|
|
||||||
|
assertNull(primary.get(o2));
|
||||||
|
assertNull(secondary.get(o2));
|
||||||
|
Object r4 = service.multiCache(o2);
|
||||||
|
assertSame(r4, primary.get(o2).get());
|
||||||
|
assertSame(r4, secondary.get(o2).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMultiEvict(CacheableService<?> service) {
|
||||||
|
Object o1 = new Object();
|
||||||
|
|
||||||
|
Object r1 = service.multiCache(o1);
|
||||||
|
Object r2 = service.multiCache(o1);
|
||||||
|
|
||||||
|
Cache primary = cm.getCache("primary");
|
||||||
|
Cache secondary = cm.getCache("secondary");
|
||||||
|
|
||||||
|
assertSame(r1, r2);
|
||||||
|
assertSame(r1, primary.get(o1).get());
|
||||||
|
assertSame(r1, secondary.get(o1).get());
|
||||||
|
|
||||||
|
service.multiEvict(o1);
|
||||||
|
assertNull(primary.get(o1));
|
||||||
|
assertNull(secondary.get(o1));
|
||||||
|
|
||||||
|
Object r3 = service.multiCache(o1);
|
||||||
|
Object r4 = service.multiCache(o1);
|
||||||
|
assertNotSame(r1, r3);
|
||||||
|
assertSame(r3, r4);
|
||||||
|
|
||||||
|
assertSame(r3, primary.get(o1).get());
|
||||||
|
assertSame(r4, secondary.get(o1).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMultiPut(CacheableService<?> service) {
|
||||||
|
Object o = Integer.valueOf(1);
|
||||||
|
|
||||||
|
Cache primary = cm.getCache("primary");
|
||||||
|
Cache secondary = cm.getCache("secondary");
|
||||||
|
|
||||||
|
assertNull(primary.get(o));
|
||||||
|
assertNull(secondary.get(o));
|
||||||
|
Object r1 = service.multiUpdate(o);
|
||||||
|
assertSame(r1, primary.get(o).get());
|
||||||
|
assertSame(r1, secondary.get(o).get());
|
||||||
|
|
||||||
|
o = Integer.valueOf(2);
|
||||||
|
assertNull(primary.get(o));
|
||||||
|
assertNull(secondary.get(o));
|
||||||
|
Object r2 = service.multiUpdate(o);
|
||||||
|
assertSame(r2, primary.get(o).get());
|
||||||
|
assertSame(r2, secondary.get(o).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMultiCacheAndEvict(CacheableService<?> service) {
|
||||||
|
String methodName = "multiCacheAndEvict";
|
||||||
|
|
||||||
|
Cache primary = cm.getCache("primary");
|
||||||
|
Cache secondary = cm.getCache("secondary");
|
||||||
|
Object key = Integer.valueOf(1);
|
||||||
|
|
||||||
|
secondary.put(key, key);
|
||||||
|
|
||||||
|
assertNull(secondary.get(methodName));
|
||||||
|
assertSame(key, secondary.get(key).get());
|
||||||
|
|
||||||
|
Object r1 = service.multiCacheAndEvict(key);
|
||||||
|
assertSame(r1, service.multiCacheAndEvict(key));
|
||||||
|
|
||||||
|
// assert the method name is used
|
||||||
|
assertSame(r1, primary.get(methodName).get());
|
||||||
|
assertNull(secondary.get(methodName));
|
||||||
|
assertNull(secondary.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMultiConditionalCacheAndEvict(CacheableService<?> service) {
|
||||||
|
Cache primary = cm.getCache("primary");
|
||||||
|
Cache secondary = cm.getCache("secondary");
|
||||||
|
Object key = Integer.valueOf(1);
|
||||||
|
|
||||||
|
secondary.put(key, key);
|
||||||
|
|
||||||
|
assertNull(primary.get(key));
|
||||||
|
assertSame(key, secondary.get(key).get());
|
||||||
|
|
||||||
|
Object r1 = service.multiConditionalCacheAndEvict(key);
|
||||||
|
Object r3 = service.multiConditionalCacheAndEvict(key);
|
||||||
|
|
||||||
|
assertTrue(!r1.equals(r3));
|
||||||
|
assertNull(primary.get(key));
|
||||||
|
|
||||||
|
Object key2 = Integer.valueOf(3);
|
||||||
|
Object r2 = service.multiConditionalCacheAndEvict(key2);
|
||||||
|
assertSame(r2, service.multiConditionalCacheAndEvict(key2));
|
||||||
|
|
||||||
|
// assert the method name is used
|
||||||
|
assertSame(r2, primary.get(key2).get());
|
||||||
|
assertNull(secondary.get(key2));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCacheable() throws Exception {
|
public void testCacheable() throws Exception {
|
||||||
testCacheable(cs);
|
testCacheable(cs);
|
||||||
|
@ -125,7 +393,32 @@ public abstract class AbstractAnnotationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidate() throws Exception {
|
public void testInvalidate() throws Exception {
|
||||||
testInvalidate(cs);
|
testEvict(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEarlyInvalidate() throws Exception {
|
||||||
|
testEvictEarly(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEvictWithException() throws Exception {
|
||||||
|
testEvictException(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEvictAll() throws Exception {
|
||||||
|
testEvictAll(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidateWithKey() throws Exception {
|
||||||
|
testEvictWKey(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEarlyInvalidateWithKey() throws Exception {
|
||||||
|
testEvictWKeyEarly(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -145,7 +438,70 @@ public abstract class AbstractAnnotationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClassCacheInvalidate() throws Exception {
|
public void testClassCacheInvalidate() throws Exception {
|
||||||
testInvalidate(ccs);
|
testEvict(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassEarlyInvalidate() throws Exception {
|
||||||
|
testEvictEarly(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassEvictAll() throws Exception {
|
||||||
|
testEvictAll(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassEvictWithException() throws Exception {
|
||||||
|
testEvictException(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassCacheInvalidateWKey() throws Exception {
|
||||||
|
testEvictWKey(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassEarlyInvalidateWithKey() throws Exception {
|
||||||
|
testEvictWKeyEarly(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullValue() throws Exception {
|
||||||
|
testNullValue(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassNullValue() throws Exception {
|
||||||
|
Object key = new Object();
|
||||||
|
assertNull(ccs.nullValue(key));
|
||||||
|
int nr = ccs.nullInvocations().intValue();
|
||||||
|
assertNull(ccs.nullValue(key));
|
||||||
|
assertEquals(nr, ccs.nullInvocations().intValue());
|
||||||
|
assertNull(ccs.nullValue(new Object()));
|
||||||
|
// the check method is also cached
|
||||||
|
assertEquals(nr, ccs.nullInvocations().intValue());
|
||||||
|
assertEquals(nr + 1, AnnotatedClassCacheableService.nullInvocations.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMethodName() throws Exception {
|
||||||
|
testMethodName(cs, "name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassMethodName() throws Exception {
|
||||||
|
testMethodName(ccs, "namedefault");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullArg() throws Exception {
|
||||||
|
testNullArg(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassNullArg() throws Exception {
|
||||||
|
testNullArg(ccs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -168,4 +524,73 @@ public abstract class AbstractAnnotationTest {
|
||||||
testUncheckedThrowable(ccs);
|
testUncheckedThrowable(ccs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate() {
|
||||||
|
testCacheUpdate(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassUpdate() {
|
||||||
|
testCacheUpdate(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConditionalUpdate() {
|
||||||
|
testConditionalCacheUpdate(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassConditionalUpdate() {
|
||||||
|
testConditionalCacheUpdate(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiCache() {
|
||||||
|
testMultiCache(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassMultiCache() {
|
||||||
|
testMultiCache(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiEvict() {
|
||||||
|
testMultiEvict(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassMultiEvict() {
|
||||||
|
testMultiEvict(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiPut() {
|
||||||
|
testMultiPut(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassMultiPut() {
|
||||||
|
testMultiPut(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiCacheAndEvict() {
|
||||||
|
testMultiCacheAndEvict(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassMultiCacheAndEvict() {
|
||||||
|
testMultiCacheAndEvict(ccs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiConditionalCacheAndEvict() {
|
||||||
|
testMultiConditionalCacheAndEvict(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassMultiConditionalCacheAndEvict() {
|
||||||
|
testMultiConditionalCacheAndEvict(ccs);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.cache.aspectj;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Costin Leau
|
||||||
|
*/
|
||||||
|
public class AspectJAnnotationTest extends AbstractAnnotationTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ApplicationContext getApplicationContext() {
|
||||||
|
return new GenericXmlApplicationContext("/org/springframework/cache/config/annotation-cache-aspectj.xml");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2010 the original author or authors.
|
* Copyright 2010-2011 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.
|
||||||
|
@ -19,15 +19,18 @@ package org.springframework.cache.config;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
|
import org.springframework.cache.annotation.CachePut;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
|
import org.springframework.cache.annotation.Caching;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
@Cacheable("default")
|
@Cacheable("default")
|
||||||
public class AnnotatedClassCacheableService implements CacheableService {
|
public class AnnotatedClassCacheableService implements CacheableService<Object> {
|
||||||
|
|
||||||
private AtomicLong counter = new AtomicLong();
|
private final AtomicLong counter = new AtomicLong();
|
||||||
|
public static final AtomicLong nullInvocations = new AtomicLong();
|
||||||
|
|
||||||
public Object cache(Object arg1) {
|
public Object cache(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
|
@ -41,11 +44,63 @@ public class AnnotatedClassCacheableService implements CacheableService {
|
||||||
public void invalidate(Object arg1) {
|
public void invalidate(Object arg1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CacheEvict("default")
|
||||||
|
public void evictWithException(Object arg1) {
|
||||||
|
throw new RuntimeException("exception thrown - evict should NOT occur");
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheEvict(value = "default", allEntries = true)
|
||||||
|
public void evictAll(Object arg1) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheEvict(value = "default", afterInvocation = false)
|
||||||
|
public void evictEarly(Object arg1) {
|
||||||
|
throw new RuntimeException("exception thrown - evict should still occur");
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheEvict(value = "default", key = "#p0")
|
||||||
|
public void evict(Object arg1, Object arg2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheEvict(value = "default", key = "#p0", afterInvocation = false)
|
||||||
|
public void invalidateEarly(Object arg1, Object arg2) {
|
||||||
|
throw new RuntimeException("exception thrown - evict should still occur");
|
||||||
|
}
|
||||||
|
|
||||||
@Cacheable(value = "default", key = "#p0")
|
@Cacheable(value = "default", key = "#p0")
|
||||||
public Object key(Object arg1, Object arg2) {
|
public Object key(Object arg1, Object arg2) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Cacheable(value = "default", key = "#root.methodName + #root.caches[0].name")
|
||||||
|
public Object name(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
||||||
|
public Object rootVars(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@CachePut("default")
|
||||||
|
public Object update(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@CachePut(value = "default", condition = "#arg.equals(3)")
|
||||||
|
public Object conditionalUpdate(Object arg) {
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object nullValue(Object arg1) {
|
||||||
|
nullInvocations.incrementAndGet();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number nullInvocations() {
|
||||||
|
return nullInvocations.get();
|
||||||
|
}
|
||||||
|
|
||||||
public Long throwChecked(Object arg1) throws Exception {
|
public Long throwChecked(Object arg1) throws Exception {
|
||||||
throw new UnsupportedOperationException(arg1.toString());
|
throw new UnsupportedOperationException(arg1.toString());
|
||||||
}
|
}
|
||||||
|
@ -53,4 +108,31 @@ public class AnnotatedClassCacheableService implements CacheableService {
|
||||||
public Long throwUnchecked(Object arg1) {
|
public Long throwUnchecked(Object arg1) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// multi annotations
|
||||||
|
|
||||||
|
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
||||||
|
public Object multiCache(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
||||||
|
public Object multiEvict(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
||||||
|
public Object multiCacheAndEvict(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||||
|
public Object multiConditionalCacheAndEvict(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
||||||
|
public Object multiUpdate(Object arg1) {
|
||||||
|
return arg1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2010 the original author or authors.
|
* Copyright 2010-2011 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.
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.cache.config;
|
package org.springframework.cache.config;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic service interface.
|
* Basic service interface.
|
||||||
*
|
*
|
||||||
|
@ -28,11 +27,44 @@ public interface CacheableService<T> {
|
||||||
|
|
||||||
void invalidate(Object arg1);
|
void invalidate(Object arg1);
|
||||||
|
|
||||||
|
void evictEarly(Object arg1);
|
||||||
|
|
||||||
|
void evictAll(Object arg1);
|
||||||
|
|
||||||
|
void evictWithException(Object arg1);
|
||||||
|
|
||||||
|
void evict(Object arg1, Object arg2);
|
||||||
|
|
||||||
|
void invalidateEarly(Object arg1, Object arg2);
|
||||||
|
|
||||||
T conditional(int field);
|
T conditional(int field);
|
||||||
|
|
||||||
T key(Object arg1, Object arg2);
|
T key(Object arg1, Object arg2);
|
||||||
|
|
||||||
|
T name(Object arg1);
|
||||||
|
|
||||||
|
T nullValue(Object arg1);
|
||||||
|
|
||||||
|
T update(Object arg1);
|
||||||
|
|
||||||
|
T conditionalUpdate(Object arg2);
|
||||||
|
|
||||||
|
Number nullInvocations();
|
||||||
|
|
||||||
|
T rootVars(Object arg1);
|
||||||
|
|
||||||
T throwChecked(Object arg1) throws Exception;
|
T throwChecked(Object arg1) throws Exception;
|
||||||
|
|
||||||
T throwUnchecked(Object arg1);
|
T throwUnchecked(Object arg1);
|
||||||
|
|
||||||
|
// multi annotations
|
||||||
|
T multiCache(Object arg1);
|
||||||
|
|
||||||
|
T multiEvict(Object arg1);
|
||||||
|
|
||||||
|
T multiCacheAndEvict(Object arg1);
|
||||||
|
|
||||||
|
T multiConditionalCacheAndEvict(Object arg1);
|
||||||
|
|
||||||
|
T multiUpdate(Object arg1);
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2010 the original author or authors.
|
* Copyright 2010-2011 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.
|
||||||
|
@ -19,8 +19,9 @@ package org.springframework.cache.config;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
|
import org.springframework.cache.annotation.CachePut;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
|
import org.springframework.cache.annotation.Caching;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple cacheable service
|
* Simple cacheable service
|
||||||
|
@ -29,7 +30,8 @@ import org.springframework.cache.annotation.Cacheable;
|
||||||
*/
|
*/
|
||||||
public class DefaultCacheableService implements CacheableService<Long> {
|
public class DefaultCacheableService implements CacheableService<Long> {
|
||||||
|
|
||||||
private AtomicLong counter = new AtomicLong();
|
private final AtomicLong counter = new AtomicLong();
|
||||||
|
private final AtomicLong nullInvocations = new AtomicLong();
|
||||||
|
|
||||||
@Cacheable("default")
|
@Cacheable("default")
|
||||||
public Long cache(Object arg1) {
|
public Long cache(Object arg1) {
|
||||||
|
@ -40,6 +42,29 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
||||||
public void invalidate(Object arg1) {
|
public void invalidate(Object arg1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CacheEvict("default")
|
||||||
|
public void evictWithException(Object arg1) {
|
||||||
|
throw new RuntimeException("exception thrown - evict should NOT occur");
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheEvict(value = "default", allEntries = true)
|
||||||
|
public void evictAll(Object arg1) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheEvict(value = "default", afterInvocation = false)
|
||||||
|
public void evictEarly(Object arg1) {
|
||||||
|
throw new RuntimeException("exception thrown - evict should still occur");
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheEvict(value = "default", key = "#p0")
|
||||||
|
public void evict(Object arg1, Object arg2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheEvict(value = "default", key = "#p0", afterInvocation = false)
|
||||||
|
public void invalidateEarly(Object arg1, Object arg2) {
|
||||||
|
throw new RuntimeException("exception thrown - evict should still occur");
|
||||||
|
}
|
||||||
|
|
||||||
@Cacheable(value = "default", condition = "#classField == 3")
|
@Cacheable(value = "default", condition = "#classField == 3")
|
||||||
public Long conditional(int classField) {
|
public Long conditional(int classField) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
|
@ -50,6 +75,36 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Cacheable(value = "default", key = "#root.methodName")
|
||||||
|
public Long name(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
||||||
|
public Long rootVars(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@CachePut("default")
|
||||||
|
public Long update(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@CachePut(value = "default", condition = "#arg.equals(3)")
|
||||||
|
public Long conditionalUpdate(Object arg) {
|
||||||
|
return Long.valueOf(arg.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Cacheable("default")
|
||||||
|
public Long nullValue(Object arg1) {
|
||||||
|
nullInvocations.incrementAndGet();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number nullInvocations() {
|
||||||
|
return nullInvocations.get();
|
||||||
|
}
|
||||||
|
|
||||||
@Cacheable("default")
|
@Cacheable("default")
|
||||||
public Long throwChecked(Object arg1) throws Exception {
|
public Long throwChecked(Object arg1) throws Exception {
|
||||||
throw new Exception(arg1.toString());
|
throw new Exception(arg1.toString());
|
||||||
|
@ -59,4 +114,31 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
||||||
public Long throwUnchecked(Object arg1) {
|
public Long throwUnchecked(Object arg1) {
|
||||||
throw new UnsupportedOperationException(arg1.toString());
|
throw new UnsupportedOperationException(arg1.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// multi annotations
|
||||||
|
|
||||||
|
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
||||||
|
public Long multiCache(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
||||||
|
public Long multiEvict(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
||||||
|
public Long multiCacheAndEvict(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||||
|
public Long multiConditionalCacheAndEvict(Object arg1) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
||||||
|
public Long multiUpdate(Object arg1) {
|
||||||
|
return Long.valueOf(arg1.toString());
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,13 +13,15 @@
|
||||||
|
|
||||||
<bean id="cacheAspect" class="org.springframework.cache.aspectj.AnnotationCacheAspect" factory-method="aspectOf">
|
<bean id="cacheAspect" class="org.springframework.cache.aspectj.AnnotationCacheAspect" factory-method="aspectOf">
|
||||||
<property name="cacheManager" ref="cacheManager"/>
|
<property name="cacheManager" ref="cacheManager"/>
|
||||||
<property name="cacheOperationSource" ref="annotationSource"/>
|
<property name="cacheOperationSources" ref="annotationSource"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
|
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
|
||||||
<property name="caches">
|
<property name="caches">
|
||||||
<set>
|
<set>
|
||||||
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
|
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
|
||||||
|
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="primary"/>
|
||||||
|
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="secondary"/>
|
||||||
</set>
|
</set>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
Loading…
Reference in New Issue