Mar 13 2008

Spring AOP with aspectJ and JDK5 annotations

Published by Gilles at 4:01 pm under Spring

The logger aspect
loggeraspect.java

The intention of this aspect is to explain the concepts of pointcut and the different code advices:

JAVA:
  1. package be.loadit.aspects;
  2.  
  3. import org.apache.log4j.Logger;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.AfterReturning;
  6. import org.aspectj.lang.annotation.AfterThrowing;
  7. import org.aspectj.lang.annotation.Around;
  8. import org.aspectj.lang.annotation.Aspect;
  9. import org.aspectj.lang.annotation.Before;
  10. import org.aspectj.lang.annotation.Pointcut;
  11.  
  12. @Aspect
  13. public class LoggerAspect {
  14. private final Logger logger = Logger.getLogger(getClass());
  15.  
  16. //Pointcut definitions on a method signature basis
  17. //All public methods
  18. @Pointcut("execution(public * *(..))")
  19. private void publicMethod() {}
  20.  
  21. //All public setters
  22. @Pointcut("execution(public * set*(..))")
  23. private void publicSetMethod() {}
  24.  
  25. //All public getters
  26. @Pointcut("execution(public * get*(..))")
  27. private void publicGetMethod() {}
  28.  
  29. @Pointcut("within(be.loadit.service..*)")
  30. public void inServiceLayer() {}
  31.  
  32. //The code advices
  33.  
  34. @Before("inServiceLayer()")
  35. public void beforePublic(){
  36. if(logger.isDebugEnabled()) {
  37. logger.debug("Before method call");
  38. }
  39. }
  40.  
  41. @AfterReturning("publicMethod()")
  42. public void afterPublicReturning(){
  43. if(logger.isDebugEnabled()) {
  44. logger.debug("After returning");
  45. }
  46. }
  47.  
  48. @AfterThrowing(pointcut="publicMethod()",throwing="exception")
  49. public void afterPublicThrowing(Throwable exception){
  50. if(logger.isDebugEnabled()) {
  51. logger.debug("After throwing");
  52. }
  53. }
  54.  
  55. //Before and after = around
  56. //&& !publicSetMethod() && !publicGetMethod()"
  57. @Around("publicMethod()")
  58. public Object aroundPublic(final ProceedingJoinPoint pjp)
  59. throws Throwable {
  60.  
  61. if(logger.isDebugEnabled()) {
  62. logger.debug("Around: before");
  63. logger.debug("Calling " + pjp.getSignature().getName());
  64. Object[] args = pjp.getArgs();
  65. for (int i = 0; i <args.length; i++) {
  66. logger.debug("with arg: " +args[i].toString());
  67. }
  68.  
  69. }
  70.  
  71. final Object retVal = pjp.proceed();
  72.  
  73. if(logger.isDebugEnabled()) {
  74. logger.debug("Around: after");
  75. logger.debug("Calling " + pjp.getSignature().getName());
  76. }a
  77. return retVal;
  78. }
  79.  
  80. }

Our test class
persontest.java

JAVA:
  1. package be.loadit.tests;
  2. import .util.Observer;
  3. import org.junit.Test;
  4. import org.springframework.test.context.ContextConfiguration;
  5. import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
  6. import be.loadit.service.Person;
  7. @ContextConfiguration(locations={"/applicationContext.xml", "/applicationContext-.xml"})
  8. public class PersonTest extends AbstractJUnit4SpringContextTests {
  9. @Test
  10. public void testPerson() {
  11. Person person =(Person)applicationContext.getBean("Person");
  12. person.setName("Gilles");
  13. person.setAge(29);
  14. System.out.println("Name: " +person.getName());
  15. System.out.println("Age: " +person.getAge());
  16. Observer observer =(Observer)applicationContext.getBean("DummyObserver");
  17. }
  18. }

Output

CODE:
  1. 0    [main] DEBUG be.loadit.aspects.LoggerAspect  - Before method call
  2. 0    [main] DEBUG be.loadit.aspects.LoggerAspect  - Around: before
  3. 0    [main] DEBUG be.loadit.aspects.LoggerAspect  - Calling setName
  4. 0    [main] DEBUG be.loadit.aspects.LoggerAspect  - with arg: Gilles
  5. Monitoring Call
  6. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - After returning
  7. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Around: after
  8. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Calling setName
  9. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Before method call
  10. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Around: before
  11. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Calling setAge
  12. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - with arg: 29
  13. Monitoring Call
  14. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - After returning
  15. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Around: after
  16. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Calling setAge
  17. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Before method call
  18. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Around: before
  19. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Calling getName
  20. Monitoring Call
  21. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - After returning
  22. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Around: after
  23. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Calling getName
  24. Name: Gilles
  25. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Before method call
  26. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Around: before
  27. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Calling getAge
  28. Monitoring Call
  29. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - After returning
  30. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Around: after
  31. 16   [main] DEBUG be.loadit.aspects.LoggerAspect  - Calling getAge
  32. Age: 29

Pages: 1 2 3 4 5 6

Trackback URI | Comments RSS

Leave a Reply