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