diff --git a/spring-mvc-java/pom.xml b/spring-mvc-java/pom.xml index 5875af5631..772bbbb219 100644 --- a/spring-mvc-java/pom.xml +++ b/spring-mvc-java/pom.xml @@ -38,6 +38,38 @@ runtime + + + org.springframework + spring-aop + ${org.springframework.version} + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + + org.slf4j + slf4j-log4j12 + ${org.slf4j.version} + + @@ -67,6 +99,13 @@ test + + org.springframework + spring-test + ${org.springframework.version} + test + + @@ -175,6 +214,8 @@ 2.7 1.4.15 + + 1.8.7 \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/org/baeldung/aop/PerformanceAspect.java b/spring-mvc-java/src/main/java/org/baeldung/aop/PerformanceAspect.java new file mode 100644 index 0000000000..12d6bc4e69 --- /dev/null +++ b/spring-mvc-java/src/main/java/org/baeldung/aop/PerformanceAspect.java @@ -0,0 +1,31 @@ +package org.baeldung.aop; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +@Aspect +@Component +public class PerformanceAspect { + + private static Logger logger = Logger.getLogger(PerformanceAspect.class.getName()); + + @Pointcut("within(@org.springframework.stereotype.Repository *)") + public void repositoryClassMethods() {}; + + @Around("repositoryClassMethods()") + public Object measureMethodExecutionTime(ProceedingJoinPoint pjp) throws Throwable { + long start = System.nanoTime(); + Object retval = pjp.proceed(); + long end = System.nanoTime(); + String methodName = pjp.getSignature().getName(); + logger.info("Execution of " + methodName + " took " + TimeUnit.NANOSECONDS.toMillis(end - start) + " ms"); + return retval; + } + +} diff --git a/spring-mvc-java/src/main/java/org/baeldung/dao/FooDao.java b/spring-mvc-java/src/main/java/org/baeldung/dao/FooDao.java new file mode 100644 index 0000000000..fbd7f4c717 --- /dev/null +++ b/spring-mvc-java/src/main/java/org/baeldung/dao/FooDao.java @@ -0,0 +1,10 @@ +package org.baeldung.dao; + +import org.springframework.stereotype.Repository; + +@Repository +public class FooDao { + public String findById(Long id) { + return "Bazz"; + } +} diff --git a/spring-mvc-java/src/test/java/org/baeldung/aop/AopPerformanceTest.java b/spring-mvc-java/src/test/java/org/baeldung/aop/AopPerformanceTest.java new file mode 100644 index 0000000000..82af95957a --- /dev/null +++ b/spring-mvc-java/src/test/java/org/baeldung/aop/AopPerformanceTest.java @@ -0,0 +1,69 @@ +package org.baeldung.aop; + +import org.baeldung.config.TestConfig; +import org.baeldung.dao.FooDao; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {TestConfig.class}, loader = AnnotationConfigContextLoader.class) +public class AopPerformanceTest { + + @Before + public void setUp() { + logEventHandler = new Handler() { + @Override + public void publish(LogRecord record) { + messages.add(record.getMessage()); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }; + + messages = new ArrayList<>(); + } + + @Autowired + private FooDao dao; + + private Handler logEventHandler; + + private List messages; + + @Test + public void givenPerformanceAspect_whenCallDaoMethod_thenPerformanceMeasurementAdviceIsCalled() { + Logger logger = Logger.getLogger(PerformanceAspect.class.getName()); + logger.addHandler(logEventHandler); + + final String entity = dao.findById(1L); + assertThat(entity, notNullValue()); + assertThat(messages, hasSize(1)); + + String logMessage = messages.get(0); + Pattern pattern = Pattern.compile("Execution of findById took \\d+ ms"); + assertTrue(pattern.matcher(logMessage).matches()); + } +} diff --git a/spring-mvc-java/src/test/java/org/baeldung/config/TestConfig.java b/spring-mvc-java/src/test/java/org/baeldung/config/TestConfig.java new file mode 100644 index 0000000000..60786a108c --- /dev/null +++ b/spring-mvc-java/src/test/java/org/baeldung/config/TestConfig.java @@ -0,0 +1,11 @@ +package org.baeldung.config; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +@Configuration +@ComponentScan(basePackages = {"org.baeldung.dao", "org.baeldung.aop"}) +@EnableAspectJAutoProxy +public class TestConfig { +} diff --git a/spring-mvc-java/src/test/resources/log4j.properties b/spring-mvc-java/src/test/resources/log4j.properties new file mode 100644 index 0000000000..6193d62fd8 --- /dev/null +++ b/spring-mvc-java/src/test/resources/log4j.properties @@ -0,0 +1,9 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=WARN, A1 + +# A1 is set to be a ConsoleAppender. +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file