BAEL-6300: Invoking Spring Cache @Cacheable from Another Method of the Same Bean (#14689)
* BAEL-6300: Problem Reproduction * BAEL-6300: Internal Invocation with External Reference * BAEL-6300: compile-time weaving * BAEL-6300: load-time weaving
This commit is contained in:
parent
29c9c5dba9
commit
8c3d581fa9
|
@ -51,4 +51,119 @@
|
|||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>no-weaving</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>com.baeldung.selfinvocation.CompileTimeWeavingIntegrationTest</exclude>
|
||||
<exclude>com.baeldung.selfinvocation.LoadTimeWeavingIntegrationTest</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>compile-time-weaving</id>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>com.baeldung.selfinvocation.CompileTimeWeavingIntegrationTest</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>${aspectj-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<complianceLevel>${java.version}</complianceLevel>
|
||||
<Xlint>ignore</Xlint>
|
||||
<encoding>UTF-8</encoding>
|
||||
<aspectLibraries>
|
||||
<aspectLibrary>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
</aspectLibrary>
|
||||
</aspectLibraries>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>load-time-weaving</id>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<argLine>
|
||||
--add-opens java.base/java.lang=ALL-UNNAMED
|
||||
--add-opens java.base/java.util=ALL-UNNAMED
|
||||
-javaagent:"${settings.localRepository}"/org/aspectj/aspectjweaver/${aspectjweaver.version}/aspectjweaver-${aspectjweaver.version}.jar
|
||||
-javaagent:"${settings.localRepository}"/org/springframework/spring-instrument/${spring.version}/spring-instrument-${spring.version}.jar
|
||||
</argLine>
|
||||
<useSystemClassLoader>true</useSystemClassLoader>
|
||||
<forkMode>always</forkMode>
|
||||
<includes>
|
||||
<include>com.baeldung.selfinvocation.LoadTimeWeavingIntegrationTest</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<aspectj-plugin.version>1.14.0</aspectj-plugin.version>
|
||||
<spring.version>5.3.27</spring.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -2,8 +2,16 @@ package com.baeldung;
|
|||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackages = { "com.baeldung" }, excludeFilters = {
|
||||
@ComponentScan.Filter(type = FilterType.ANNOTATION,
|
||||
value = { SpringBootApplication.class})
|
||||
})
|
||||
@EnableCaching
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.selfinvocation;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableCaching(mode = AdviceMode.ASPECTJ)
|
||||
@ComponentScan(basePackages = { "com.baeldung" }, excludeFilters = {
|
||||
@ComponentScan.Filter(type = FilterType.ANNOTATION,
|
||||
value = { SpringBootApplication.class})
|
||||
})
|
||||
public class CompileTimeWeavingApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CompileTimeWeavingApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.selfinvocation;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.EnableLoadTimeWeaving;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableCaching(mode = AdviceMode.ASPECTJ)
|
||||
@EnableLoadTimeWeaving
|
||||
public class LoadTimeWeavingApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(LoadTimeWeavingApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung.selfinvocation;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "square")
|
||||
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
public class MathService {
|
||||
|
||||
@Autowired
|
||||
private MathService self;
|
||||
private final AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
@CacheEvict(allEntries = true)
|
||||
public AtomicInteger resetCounter() {
|
||||
counter.set(0);
|
||||
return counter;
|
||||
}
|
||||
|
||||
@Cacheable(key = "#n")
|
||||
public double square(double n) {
|
||||
counter.incrementAndGet();
|
||||
return n * n;
|
||||
}
|
||||
|
||||
public double sumOfSquareOf2() {
|
||||
return this.square(2) + this.square(2);
|
||||
}
|
||||
|
||||
public double sumOfSquareOf3() {
|
||||
return self.square(3) + self.square(3);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
<logger name="org.springframework.aop.interceptor.PerformanceMonitorInterceptor" level="TRACE" />
|
||||
|
||||
<logger name="org.aspectj.weaver" level="WARN" />
|
||||
|
||||
<root level="TRACE">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.selfinvocation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(classes = CompileTimeWeavingApplication.class)
|
||||
class CompileTimeWeavingIntegrationTest {
|
||||
|
||||
@Resource
|
||||
private MathService mathService;
|
||||
|
||||
@Test
|
||||
void givenCacheableMethod_whenInvokingByInternalCall_thenCacheIsTriggered() {
|
||||
AtomicInteger counter = mathService.resetCounter();
|
||||
|
||||
assertThat(mathService.sumOfSquareOf2()).isEqualTo(8);
|
||||
assertThat(counter.get()).isEqualTo(1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.selfinvocation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(classes = LoadTimeWeavingApplication.class)
|
||||
class LoadTimeWeavingIntegrationTest {
|
||||
|
||||
@Resource
|
||||
private MathService mathService;
|
||||
|
||||
@Test
|
||||
void givenCacheableMethod_whenInvokingByInternalCall_thenCacheIsTriggered() {
|
||||
AtomicInteger counter = mathService.resetCounter();
|
||||
|
||||
assertThat(mathService.sumOfSquareOf2()).isEqualTo(8);
|
||||
assertThat(counter.get()).isEqualTo(1);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.baeldung.selfinvocation;
|
||||
|
||||
import com.baeldung.Application;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(classes = Application.class)
|
||||
class MathServiceIntegrationTest {
|
||||
|
||||
@Resource
|
||||
private MathService mathService;
|
||||
|
||||
@Test
|
||||
void givenCacheableMethod_whenInvokedForSecondTime_thenCounterShouldNotIncrease() {
|
||||
AtomicInteger counter = mathService.resetCounter();
|
||||
assertThat(mathService.square(2)).isEqualTo(4);
|
||||
assertThat(counter.get()).isEqualTo(1);
|
||||
|
||||
mathService.square(2);
|
||||
assertThat(counter.get()).isEqualTo(1);
|
||||
|
||||
mathService.square(3);
|
||||
assertThat(counter.get()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenCacheableMethod_whenInvokingByInternalCall_thenCacheIsNotTriggered() {
|
||||
AtomicInteger counter = mathService.resetCounter();
|
||||
|
||||
assertThat(mathService.sumOfSquareOf2()).isEqualTo(8);
|
||||
assertThat(counter.get()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenCacheableMethod_whenInvokingByExternalCall_thenCacheIsTriggered() {
|
||||
AtomicInteger counter = mathService.resetCounter();
|
||||
|
||||
assertThat(mathService.sumOfSquareOf3()).isEqualTo(18);
|
||||
assertThat(counter.get()).isEqualTo(1);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue