diff --git a/spring-aop-2/pom.xml b/spring-aop-2/pom.xml
index 056e248a3c..206e1d7d7c 100644
--- a/spring-aop-2/pom.xml
+++ b/spring-aop-2/pom.xml
@@ -51,4 +51,119 @@
+
+
+ no-weaving
+
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ com.baeldung.selfinvocation.CompileTimeWeavingIntegrationTest
+ com.baeldung.selfinvocation.LoadTimeWeavingIntegrationTest
+
+
+
+
+
+
+
+
+ compile-time-weaving
+
+
+
+ org.springframework
+ spring-aspects
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ com.baeldung.selfinvocation.CompileTimeWeavingIntegrationTest
+
+
+
+
+ org.codehaus.mojo
+ aspectj-maven-plugin
+ ${aspectj-plugin.version}
+
+ ${java.version}
+ ${java.version}
+ ${java.version}
+ ignore
+ UTF-8
+
+
+ org.springframework
+ spring-aspects
+
+
+
+
+
+
+ compile
+
+
+
+
+
+
+
+
+
+ load-time-weaving
+
+
+
+ org.springframework
+ spring-aspects
+
+
+ org.springframework
+ spring-tx
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ --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
+
+ true
+ always
+
+ com.baeldung.selfinvocation.LoadTimeWeavingIntegrationTest
+
+
+
+
+
+
+
+
+
+ 1.14.0
+ 5.3.27
+
+
\ No newline at end of file
diff --git a/spring-aop-2/src/main/java/com/baeldung/Application.java b/spring-aop-2/src/main/java/com/baeldung/Application.java
index c0490d50c6..cc64447264 100644
--- a/spring-aop-2/src/main/java/com/baeldung/Application.java
+++ b/spring-aop-2/src/main/java/com/baeldung/Application.java
@@ -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) {
diff --git a/spring-aop-2/src/main/java/com/baeldung/selfinvocation/CompileTimeWeavingApplication.java b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/CompileTimeWeavingApplication.java
new file mode 100644
index 0000000000..03995dd53b
--- /dev/null
+++ b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/CompileTimeWeavingApplication.java
@@ -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);
+ }
+}
\ No newline at end of file
diff --git a/spring-aop-2/src/main/java/com/baeldung/selfinvocation/LoadTimeWeavingApplication.java b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/LoadTimeWeavingApplication.java
new file mode 100644
index 0000000000..a3dcc161b3
--- /dev/null
+++ b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/LoadTimeWeavingApplication.java
@@ -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);
+ }
+}
\ No newline at end of file
diff --git a/spring-aop-2/src/main/java/com/baeldung/selfinvocation/MathService.java b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/MathService.java
new file mode 100644
index 0000000000..993b73295f
--- /dev/null
+++ b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/MathService.java
@@ -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);
+ }
+
+}
+
diff --git a/spring-aop-2/src/main/resources/logback.xml b/spring-aop-2/src/main/resources/logback.xml
index 4eaa556705..d63707a9da 100644
--- a/spring-aop-2/src/main/resources/logback.xml
+++ b/spring-aop-2/src/main/resources/logback.xml
@@ -17,6 +17,8 @@
+
+
diff --git a/spring-aop-2/src/test/java/com/baeldung/selfinvocation/CompileTimeWeavingIntegrationTest.java b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/CompileTimeWeavingIntegrationTest.java
new file mode 100644
index 0000000000..d0522f67e5
--- /dev/null
+++ b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/CompileTimeWeavingIntegrationTest.java
@@ -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);
+ }
+}
\ No newline at end of file
diff --git a/spring-aop-2/src/test/java/com/baeldung/selfinvocation/LoadTimeWeavingIntegrationTest.java b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/LoadTimeWeavingIntegrationTest.java
new file mode 100644
index 0000000000..93c57699d6
--- /dev/null
+++ b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/LoadTimeWeavingIntegrationTest.java
@@ -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);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-aop-2/src/test/java/com/baeldung/selfinvocation/MathServiceIntegrationTest.java b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/MathServiceIntegrationTest.java
new file mode 100644
index 0000000000..24b829fa07
--- /dev/null
+++ b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/MathServiceIntegrationTest.java
@@ -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);
+ }
+
+}
\ No newline at end of file