diff --git a/spring-aop/src/main/java/com/baeldung/joinpoint/ArticleService.java b/spring-aop/src/main/java/com/baeldung/joinpoint/ArticleService.java new file mode 100644 index 0000000000..5a6b5ce63a --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/joinpoint/ArticleService.java @@ -0,0 +1,32 @@ +package com.baeldung.joinpoint; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +import static java.util.stream.Collectors.toList; + +@Service +public class ArticleService { + + public List getArticleList() { + return Arrays.asList( + "Article 1", + "Article 2" + ); + } + + public List getArticleList(String startsWithFilter) { + if (StringUtils.isBlank(startsWithFilter)) { + throw new IllegalArgumentException("startsWithFilter can't be blank"); + } + + return getArticleList() + .stream() + .filter(a -> a.startsWith(startsWithFilter)) + .collect(toList()); + } + +} diff --git a/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspect.java b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspect.java new file mode 100644 index 0000000000..a1f991e90d --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspect.java @@ -0,0 +1,27 @@ +package com.baeldung.joinpoint; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +import java.util.logging.Logger; + +@Aspect +@Component +public class JoinPointAfterThrowingAspect { + + private static final java.util.logging.Logger log = Logger.getLogger(JoinPointAfterThrowingAspect.class.getName()); + + @Pointcut("execution(* com.baeldung.joinpoint.ArticleService.getArticleList(..))") + public void articleListPointcut() { } + + @AfterThrowing( + pointcut = "articleListPointcut()", + throwing = "e" + ) + public void logExceptions(JoinPoint jp, Exception e) { + log.severe(e.getMessage()); + } +} diff --git a/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundCacheAspect.java b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundCacheAspect.java new file mode 100644 index 0000000000..dbf2b2e1e4 --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundCacheAspect.java @@ -0,0 +1,30 @@ +package com.baeldung.joinpoint; + +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.HashMap; +import java.util.Map; + +@Aspect +@Component +public class JoinPointAroundCacheAspect { + + public final static Map CACHE = new HashMap<>(); + + @Pointcut("execution(* com.baeldung.joinpoint.ArticleService.getArticleList(..))") + public void articleListPointcut() { } + + @Around("articleListPointcut()") + public Object aroundAdviceCache(ProceedingJoinPoint pjp) throws Throwable { + Object articles = CACHE.get(pjp.getArgs()); + if (articles == null) { + articles = pjp.proceed(pjp.getArgs()); + CACHE.put(pjp.getArgs(), articles); + } + return articles; + } +} diff --git a/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspect.java b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspect.java new file mode 100644 index 0000000000..8d15de150d --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspect.java @@ -0,0 +1,30 @@ +package com.baeldung.joinpoint; + +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.logging.Logger; + +@Aspect +@Component +public class JoinPointAroundExceptionAspect { + + private static final java.util.logging.Logger log = Logger.getLogger(JoinPointAroundExceptionAspect.class.getName()); + + @Pointcut("execution(* com.baeldung.joinpoint.ArticleService.getArticleList(..))") + public void articleListPointcut() { } + + @Around("articleListPointcut()") + public Object aroundAdviceException(ProceedingJoinPoint pjp) throws Throwable { + try { + return pjp.proceed(pjp.getArgs()); + } catch (Throwable e) { + log.severe(e.getMessage()); + log.info("Retrying operation"); + return pjp.proceed(pjp.getArgs()); + } + } +} diff --git a/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointBeforeAspect.java b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointBeforeAspect.java new file mode 100644 index 0000000000..4485363ff9 --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointBeforeAspect.java @@ -0,0 +1,32 @@ +package com.baeldung.joinpoint; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.logging.Logger; + +import static java.lang.String.format; + +@Aspect +@Component +public class JoinPointBeforeAspect { + + private static final Logger log = Logger.getLogger(JoinPointBeforeAspect.class.getName()); + + @Pointcut("execution(* com.baeldung.joinpoint.ArticleService.getArticleList(..))") + public void articleListPointcut() { } + + @Before("articleListPointcut()") + public void beforeAdvice(JoinPoint joinPoint) { + log.info( + format("Method %s executed with %s arguments", + joinPoint.getStaticPart().getSignature(), + Arrays.toString(joinPoint.getArgs()) + ) + ); + } +} diff --git a/spring-aop/src/test/java/com/baeldung/joinpoint/ArticleServiceIntegrationTest.java b/spring-aop/src/test/java/com/baeldung/joinpoint/ArticleServiceIntegrationTest.java new file mode 100644 index 0000000000..a67b843262 --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/joinpoint/ArticleServiceIntegrationTest.java @@ -0,0 +1,39 @@ +package com.baeldung.joinpoint; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.List; + +import static org.junit.Assert.assertFalse; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +public class ArticleServiceIntegrationTest { + + @Autowired + private ArticleService articleService; + + @Test + public void shouldGetNotEmptyArticleList() { + List articleList = articleService.getArticleList(); + + assertFalse(articleList.isEmpty()); + } + + @Test + public void shouldGetNotEmptyArticleListWithStartsWithFilter() { + List articleList = articleService.getArticleList("Article"); + + assertFalse(articleList.isEmpty()); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionIfStartsWithFilterIsBlank() { + articleService.getArticleList(" "); + } + +} diff --git a/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspectIntegrationTest.java b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspectIntegrationTest.java new file mode 100644 index 0000000000..cdef76ac0d --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspectIntegrationTest.java @@ -0,0 +1,60 @@ +package com.baeldung.joinpoint; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +@EnableAspectJAutoProxy +public class JoinPointAfterThrowingAspectIntegrationTest { + + private final List messages = new ArrayList<>(); + + @Before + public void setUp() { + Handler logEventHandler = new Handler() { + @Override + public void publish(LogRecord record) { + messages.add(record.getLevel().getName() + " " + record.getMessage()); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }; + + Logger logger = Logger.getLogger(JoinPointAfterThrowingAspect.class.getName()); + logger.addHandler(logEventHandler); + } + + @Autowired + private ArticleService articleService; + + @Test(expected = IllegalArgumentException.class) + public void shouldLogMethodSignatureBeforeExecution() { + articleService.getArticleList(" "); + + assertThat(messages, hasSize(1)); + assertTrue(messages.contains("SEVERE startsWithFilter can't be blank")); + } + +} diff --git a/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundCacheAspectIntegrationTest.java b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundCacheAspectIntegrationTest.java new file mode 100644 index 0000000000..4bd8f2ad8e --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundCacheAspectIntegrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.joinpoint; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +@EnableAspectJAutoProxy +public class JoinPointAroundCacheAspectIntegrationTest { + + @Autowired + private ArticleService articleService; + + @Test + public void shouldPopulateCache() { + assertTrue(JoinPointAroundCacheAspect.CACHE.isEmpty()); + + List articles = articleService.getArticleList(); + + assertFalse(JoinPointAroundCacheAspect.CACHE.isEmpty()); + assertEquals(JoinPointAroundCacheAspect.CACHE.size(), 1); + assertEquals(JoinPointAroundCacheAspect.CACHE.values().iterator().next(), articles); + } + +} diff --git a/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspectIntegrationTest.java b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspectIntegrationTest.java new file mode 100644 index 0000000000..dbdda30c15 --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspectIntegrationTest.java @@ -0,0 +1,60 @@ +package com.baeldung.joinpoint; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +@EnableAspectJAutoProxy +public class JoinPointAroundExceptionAspectIntegrationTest { + + private final List messages = new ArrayList<>(); + + @Before + public void setUp() { + Handler logEventHandler = new Handler() { + @Override + public void publish(LogRecord record) { + messages.add(record.getLevel().getName() + " " + record.getMessage()); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }; + + Logger logger = Logger.getLogger(JoinPointAroundExceptionAspect.class.getName()); + logger.addHandler(logEventHandler); + } + + @Autowired + private ArticleService articleService; + + @Test(expected = IllegalArgumentException.class) + public void shouldLogMethodSignatureBeforeExecution() { + articleService.getArticleList(" "); + + assertThat(messages, hasSize(1)); + assertTrue(messages.contains("INFO Retrying operation")); + } + +} diff --git a/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointBeforeAspectIntegrationTest.java b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointBeforeAspectIntegrationTest.java new file mode 100644 index 0000000000..631852d57f --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointBeforeAspectIntegrationTest.java @@ -0,0 +1,60 @@ +package com.baeldung.joinpoint; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +@EnableAspectJAutoProxy +public class JoinPointBeforeAspectIntegrationTest { + + private final List messages = new ArrayList<>(); + + @Before + public void setUp() { + Handler logEventHandler = new Handler() { + @Override + public void publish(LogRecord record) { + messages.add(record.getLevel().getName() + " " + record.getMessage()); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }; + + Logger logger = Logger.getLogger(JoinPointBeforeAspect.class.getName()); + logger.addHandler(logEventHandler); + } + + @Autowired + private ArticleService articleService; + + @Test + public void shouldLogMethodSignatureBeforeExecution() { + articleService.getArticleList(); + + assertThat(messages, hasSize(1)); + assertTrue(messages.contains("INFO Method List com.baeldung.joinpoint.ArticleService.getArticleList() executed with [] arguments")); + } + +}