From cfee9311943c3715cb1ef6a9b282eea70d701fe5 Mon Sep 17 00:00:00 2001 From: bhandy Date: Tue, 23 Mar 2021 21:52:58 -0400 Subject: [PATCH 1/5] BAEL-4844: Code for the AspectJ class annotation article. --- spring-aop/pom.xml | 43 +++++++++++++++++++ .../classmethodadvice/MyTracedService.java | 19 ++++++++ .../MyTracedServiceConsumer.java | 12 ++++++ .../aspectj/classmethodadvice/Trace.java | 12 ++++++ .../classmethodadvice/TracingAspect.aj | 19 ++++++++ spring-aop/src/main/resources/logback.xml | 2 + .../MyTracedServiceConsumerUnitTest.java | 30 +++++++++++++ .../MyTracedServiceUnitTest.java | 40 +++++++++++++++++ 8 files changed, 177 insertions(+) create mode 100644 spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedService.java create mode 100644 spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumer.java create mode 100644 spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/Trace.java create mode 100644 spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj create mode 100644 spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumerUnitTest.java create mode 100644 spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceUnitTest.java diff --git a/spring-aop/pom.xml b/spring-aop/pom.xml index 74b6f48b46..09949a95f5 100644 --- a/spring-aop/pom.xml +++ b/spring-aop/pom.xml @@ -14,6 +14,15 @@ + + org.aspectj + aspectjrt + + + org.aspectj + aspectjweaver + + org.springframework.boot spring-boot-starter-aop @@ -23,7 +32,41 @@ spring-boot-starter-test test + + org.mockito + mockito-core + test + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj-plugin.version} + + ${java.version} + ${java.version} + ${java.version} + true + true + ignore + UTF-8 + + + + + compile + + + + + + + + + 1.11 + diff --git a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedService.java b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedService.java new file mode 100644 index 0000000000..c6e0686211 --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedService.java @@ -0,0 +1,19 @@ +package com.baeldung.aspectj.classmethodadvice; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.stereotype.Component; + +@Trace +@Component +public class MyTracedService { + private static final Log LOG = LogFactory.getLog(MyTracedService.class); + + public void performSomeLogic() { + LOG.info("Inside performSomeLogic..."); + } + + public void performSomeAdditionalLogic() { + LOG.info("Inside performSomeAdditionalLogic..."); + } +} diff --git a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumer.java b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumer.java new file mode 100644 index 0000000000..fc7381dcea --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumer.java @@ -0,0 +1,12 @@ +package com.baeldung.aspectj.classmethodadvice; + +import org.springframework.stereotype.Component; + +@Component +public class MyTracedServiceConsumer { + + public MyTracedServiceConsumer(MyTracedService myTracedService) { + myTracedService.performSomeLogic(); + myTracedService.performSomeAdditionalLogic(); + } +} diff --git a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/Trace.java b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/Trace.java new file mode 100644 index 0000000000..0ab1547eeb --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/Trace.java @@ -0,0 +1,12 @@ +package com.baeldung.aspectj.classmethodadvice; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Trace { + +} diff --git a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj new file mode 100644 index 0000000000..518392e01b --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj @@ -0,0 +1,19 @@ +package com.baeldung.aspectj.classmethodadvice; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public aspect TracingAspect { + private static final Log LOG = LogFactory.getLog(TracingAspect.class); + + pointcut traceAnnotatedClasses(): within(@Trace *) && execution(* *(..)); + + Object around() : traceAnnotatedClasses() { + String signature = thisJoinPoint.getSignature().toShortString(); + LOG.trace("Entering " + signature); + Object returnValue = proceed(); + LOG.trace("Exiting " + signature); + + return returnValue; + } +} diff --git a/spring-aop/src/main/resources/logback.xml b/spring-aop/src/main/resources/logback.xml index 4eaa556705..84885fae62 100644 --- a/spring-aop/src/main/resources/logback.xml +++ b/spring-aop/src/main/resources/logback.xml @@ -17,6 +17,8 @@ + + diff --git a/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumerUnitTest.java b/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumerUnitTest.java new file mode 100644 index 0000000000..1590f41b28 --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumerUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.aspectj.classmethodadvice; + +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.verify; + +public class MyTracedServiceConsumerUnitTest { + + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Spy + private MyTracedService myTracedService; + + @Test + public void whenCallingConsumer_thenServiceIsCalled() { + doNothing().when(myTracedService).performSomeLogic(); + doNothing().when(myTracedService).performSomeAdditionalLogic(); + + new MyTracedServiceConsumer(myTracedService); + + verify(myTracedService).performSomeLogic(); + verify(myTracedService).performSomeAdditionalLogic(); + } +} \ No newline at end of file diff --git a/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceUnitTest.java b/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceUnitTest.java new file mode 100644 index 0000000000..09e36a177b --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.aspectj.classmethodadvice; + +import org.junit.Rule; +import org.junit.Test; +import org.springframework.boot.test.system.OutputCaptureRule; + +import static org.junit.Assert.assertTrue; + +/* + * When running this test class, the tests may fail unless you build the code with Maven first. You + * must ensure the AspectJ compiler executes to weave in the Aspect's logic. Without the Aspect + * weaved into the class under test, the trace logging will not be written to stdout. + */ +public class MyTracedServiceUnitTest { + + @Rule + public OutputCaptureRule outputCaptureRule = new OutputCaptureRule(); + + @Test + public void whenPerformingSomeLogic_thenTraceAndInfoOutputIsWritten() { + MyTracedService myTracedService = new MyTracedService(); + myTracedService.performSomeLogic(); + + String output = outputCaptureRule.getOut(); + assertTrue(output.contains("TracingAspect - Entering MyTracedService.performSomeLogic")); + assertTrue(output.contains("MyTracedService - Inside performSomeLogic")); + assertTrue(output.contains("TracingAspect - Exiting MyTracedService.performSomeLogic")); + } + + @Test + public void whenPerformingSomeAdditionalLogic_thenTraceAndInfoOutputIsWritten() { + MyTracedService myTracedService = new MyTracedService(); + myTracedService.performSomeAdditionalLogic(); + + String output = outputCaptureRule.getOut(); + assertTrue(output.contains("TracingAspect - Entering MyTracedService.performSomeAdditionalLogic")); + assertTrue(output.contains("MyTracedService - Inside performSomeAdditionalLogic")); + assertTrue(output.contains("TracingAspect - Exiting MyTracedService.performSomeAdditionalLogic")); + } +} \ No newline at end of file From 78faf1e871b2d7819b6afc362b7a881686c62c5b Mon Sep 17 00:00:00 2001 From: bhandy Date: Wed, 21 Apr 2021 06:47:13 -0400 Subject: [PATCH 2/5] BAEL-4844: Fixing the indentation. --- .../classmethodadvice/MyTracedService.java | 14 +++---- .../MyTracedServiceConsumer.java | 8 ++-- .../MyTracedServiceConsumerUnitTest.java | 26 ++++++------ .../MyTracedServiceUnitTest.java | 40 +++++++++---------- 4 files changed, 45 insertions(+), 43 deletions(-) diff --git a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedService.java b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedService.java index c6e0686211..7c6934e67e 100644 --- a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedService.java +++ b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedService.java @@ -7,13 +7,13 @@ import org.springframework.stereotype.Component; @Trace @Component public class MyTracedService { - private static final Log LOG = LogFactory.getLog(MyTracedService.class); + private static final Log LOG = LogFactory.getLog(MyTracedService.class); - public void performSomeLogic() { - LOG.info("Inside performSomeLogic..."); - } + public void performSomeLogic() { + LOG.info("Inside performSomeLogic..."); + } - public void performSomeAdditionalLogic() { - LOG.info("Inside performSomeAdditionalLogic..."); - } + public void performSomeAdditionalLogic() { + LOG.info("Inside performSomeAdditionalLogic..."); + } } diff --git a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumer.java b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumer.java index fc7381dcea..1d5a017230 100644 --- a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumer.java +++ b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumer.java @@ -5,8 +5,8 @@ import org.springframework.stereotype.Component; @Component public class MyTracedServiceConsumer { - public MyTracedServiceConsumer(MyTracedService myTracedService) { - myTracedService.performSomeLogic(); - myTracedService.performSomeAdditionalLogic(); - } + public MyTracedServiceConsumer(MyTracedService myTracedService) { + myTracedService.performSomeLogic(); + myTracedService.performSomeAdditionalLogic(); + } } diff --git a/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumerUnitTest.java b/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumerUnitTest.java index 1590f41b28..605ffc62c6 100644 --- a/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumerUnitTest.java +++ b/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceConsumerUnitTest.java @@ -11,20 +11,22 @@ import static org.mockito.Mockito.verify; public class MyTracedServiceConsumerUnitTest { - @Rule - public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Spy - private MyTracedService myTracedService; + @Spy + private MyTracedService myTracedService; - @Test - public void whenCallingConsumer_thenServiceIsCalled() { - doNothing().when(myTracedService).performSomeLogic(); - doNothing().when(myTracedService).performSomeAdditionalLogic(); + @Test + public void whenCallingConsumer_thenServiceIsCalled() { + doNothing().when(myTracedService) + .performSomeLogic(); + doNothing().when(myTracedService) + .performSomeAdditionalLogic(); - new MyTracedServiceConsumer(myTracedService); + new MyTracedServiceConsumer(myTracedService); - verify(myTracedService).performSomeLogic(); - verify(myTracedService).performSomeAdditionalLogic(); - } + verify(myTracedService).performSomeLogic(); + verify(myTracedService).performSomeAdditionalLogic(); + } } \ No newline at end of file diff --git a/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceUnitTest.java b/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceUnitTest.java index 09e36a177b..a5c3280d9e 100644 --- a/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceUnitTest.java +++ b/spring-aop/src/test/java/com/baeldung/aspectj/classmethodadvice/MyTracedServiceUnitTest.java @@ -13,28 +13,28 @@ import static org.junit.Assert.assertTrue; */ public class MyTracedServiceUnitTest { - @Rule - public OutputCaptureRule outputCaptureRule = new OutputCaptureRule(); + @Rule + public OutputCaptureRule outputCaptureRule = new OutputCaptureRule(); - @Test - public void whenPerformingSomeLogic_thenTraceAndInfoOutputIsWritten() { - MyTracedService myTracedService = new MyTracedService(); - myTracedService.performSomeLogic(); + @Test + public void whenPerformingSomeLogic_thenTraceAndInfoOutputIsWritten() { + MyTracedService myTracedService = new MyTracedService(); + myTracedService.performSomeLogic(); - String output = outputCaptureRule.getOut(); - assertTrue(output.contains("TracingAspect - Entering MyTracedService.performSomeLogic")); - assertTrue(output.contains("MyTracedService - Inside performSomeLogic")); - assertTrue(output.contains("TracingAspect - Exiting MyTracedService.performSomeLogic")); - } + String output = outputCaptureRule.getOut(); + assertTrue(output.contains("TracingAspect - Entering MyTracedService.performSomeLogic")); + assertTrue(output.contains("MyTracedService - Inside performSomeLogic")); + assertTrue(output.contains("TracingAspect - Exiting MyTracedService.performSomeLogic")); + } - @Test - public void whenPerformingSomeAdditionalLogic_thenTraceAndInfoOutputIsWritten() { - MyTracedService myTracedService = new MyTracedService(); - myTracedService.performSomeAdditionalLogic(); + @Test + public void whenPerformingSomeAdditionalLogic_thenTraceAndInfoOutputIsWritten() { + MyTracedService myTracedService = new MyTracedService(); + myTracedService.performSomeAdditionalLogic(); - String output = outputCaptureRule.getOut(); - assertTrue(output.contains("TracingAspect - Entering MyTracedService.performSomeAdditionalLogic")); - assertTrue(output.contains("MyTracedService - Inside performSomeAdditionalLogic")); - assertTrue(output.contains("TracingAspect - Exiting MyTracedService.performSomeAdditionalLogic")); - } + String output = outputCaptureRule.getOut(); + assertTrue(output.contains("TracingAspect - Entering MyTracedService.performSomeAdditionalLogic")); + assertTrue(output.contains("MyTracedService - Inside performSomeAdditionalLogic")); + assertTrue(output.contains("TracingAspect - Exiting MyTracedService.performSomeAdditionalLogic")); + } } \ No newline at end of file From f73a249836fa3d0aa69d5f99c2d1ad01a0577810 Mon Sep 17 00:00:00 2001 From: bhandy Date: Wed, 21 Apr 2021 06:51:23 -0400 Subject: [PATCH 3/5] BAEL-4844: Fixing the indentation. --- .../aspectj/classmethodadvice/TracingAspect.aj | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj index 518392e01b..95f3bc465d 100644 --- a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj +++ b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj @@ -4,16 +4,16 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public aspect TracingAspect { - private static final Log LOG = LogFactory.getLog(TracingAspect.class); + private static final Log LOG = LogFactory.getLog(TracingAspect.class); - pointcut traceAnnotatedClasses(): within(@Trace *) && execution(* *(..)); + pointcut traceAnnotatedClasses(): within(@Trace *) && execution(* *(..)); - Object around() : traceAnnotatedClasses() { - String signature = thisJoinPoint.getSignature().toShortString(); - LOG.trace("Entering " + signature); - Object returnValue = proceed(); - LOG.trace("Exiting " + signature); + Object around() : traceAnnotatedClasses() { + String signature = thisJoinPoint.getSignature().toShortString(); + LOG.trace("Entering " + signature); + Object returnValue = proceed(); + LOG.trace("Exiting " + signature); - return returnValue; - } + return returnValue; + } } From 883e612d455102a333ba144fbaaef4953243d533 Mon Sep 17 00:00:00 2001 From: bhandy Date: Wed, 21 Apr 2021 07:20:25 -0400 Subject: [PATCH 4/5] BAEL-4844: Adding support for tracing exceptional occurrences. --- .../aspectj/classmethodadvice/TracingAspect.aj | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj index 95f3bc465d..c80dcc0a19 100644 --- a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj +++ b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj @@ -11,9 +11,13 @@ public aspect TracingAspect { Object around() : traceAnnotatedClasses() { String signature = thisJoinPoint.getSignature().toShortString(); LOG.trace("Entering " + signature); - Object returnValue = proceed(); - LOG.trace("Exiting " + signature); - - return returnValue; + try { + return proceed(); + } catch (Exception e) { + LOG.trace("Exception thrown from " + signature, e); + throw e; + } finally { + LOG.trace("Exiting " + signature); + } } } From 1a5f9567521f2e23c646c9a1352bcfbd05db45dd Mon Sep 17 00:00:00 2001 From: bhandy Date: Fri, 23 Apr 2021 10:25:35 -0400 Subject: [PATCH 5/5] BAEL-4844: Fixed exception handling anti-pattern in the aspect. --- .../baeldung/aspectj/classmethodadvice/TracingAspect.aj | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj index c80dcc0a19..20a42940b8 100644 --- a/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj +++ b/spring-aop/src/main/java/com/baeldung/aspectj/classmethodadvice/TracingAspect.aj @@ -13,11 +13,12 @@ public aspect TracingAspect { LOG.trace("Entering " + signature); try { return proceed(); - } catch (Exception e) { - LOG.trace("Exception thrown from " + signature, e); - throw e; } finally { LOG.trace("Exiting " + signature); } } + + after() throwing (Exception e) : traceAnnotatedClasses() { + LOG.trace("Exception thrown from " + thisJoinPoint.getSignature().toShortString(), e); + } }