Announcement Announcement Module
Collapse
No announcement yet.
Configurable pointcuts Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Configurable pointcuts

    I'd like to use AOP for logging purposes. I'd like to define single utility logging aspect class and not touch it again, i.e. not to modify any code in this class. On the other hand I'd like the list of pointcuts to be configurable per module. So when I introduce module I provide for example aspect class like follows:
    @Aspect
    public class Pointcuts {
    @Pointcut("execution(public * com.xyz.modul1.pkg1.ResultController.*(javax.servl et.http.HttpServletRequest, ..))")
    public void resultController() {}

    @Pointcut("execution(public * com.xyz.modul1.pkg2.OtherController.*(javax.servle t.http.HttpServletRequest, ..))")
    public void otherController() {}

    @Pointcut("resultController() || otherController()")
    public void loggingPointcut() {}
    }
    and I'd like to enable logging for all methods matching Pointcuts.loggingPointcut() but without modyfing utility logging aspect class.
    Is it achievable with AOP? If so how? I've tried several approaches like deriving class with pointcuts to no avail.

  • #2
    Would something like this work for you?

    Common aspect
    Code:
    public abstract class CommonAspect {
    
    @Before("moduleMethod()")
    protected void handleLogging(JoinPoint joinPoint)
    // do your loggin
    }
    
    @Pointcut("")
    protected abstract void moduleMethod();
    }
    Module 1 aspect
    Code:
    @Aspect
    public class Module1LogginAspect extends CommonAspect
    {
            @Pointcut("execution(public * com.xyz.modul1.pkg1.ResultController.*(javax.servl et.http.HttpServletRequest, ..))")
    	protected void moduleMethod()
    	{
    	}
    }
    You can have the Module<N>LogginAspect inside the respective module. When you introduce a new module, you just have to subclass the CommonAspect for that module and you wont have to change the logic in common aspect.

    Downside is, if you have a lot of modules, you will be having a lot of sub classes and bean instances.

    Comment


    • #3
      Thanks it works.
      Still I wanted to split logging aspect class and pointcuts class. I've created base class for pointacuts as follows:
      Code:
      // tried interface as well to no avail
      public abstract class LoggingPointcuts {
      	@Pointcut("")
      	public abstract void pointcuts();
      }
      and derived concrete aspect class like this:
      Code:
      @Aspect
      public class Module1LoggingPointcuts extends LoggingPointcuts {
      	@Pointcut("execution(public * com.xyz.modul1.pkg1.ResultController.*(javax.servl et.http.HttpServletRequest, ..))"
      	public void pointcuts() {}
      
      }
      Logging aspect is using the base LoggingPointcuts class:
      Code:
      @Aspect
      public class LoggingAspect {
      	public static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
      
      	// tried full import path to LoggingPointcuts to no avail
      	@Around("LoggingPointcuts.pointcuts()")	
      	public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
      
      		logger.debug("logAround() is running!");
      		logger.debug("hijacked method : " + joinPoint.getSignature().getName());
      		logger.debug("hijacked arguments : "
      				+ Arrays.toString(joinPoint.getArgs()));
      
      		logger.debug("Around before is running!");
      		joinPoint.proceed(); // continue on the intercepted method
      		logger.debug("Around after is running!");
      
      		logger.debug("******");
      	}
      }
      Unfortunately it seems to fail during Spring wiring with the following exception:
      java.lang.IllegalStateException: Failed to load ApplicationContext
      ...
      Caused by: org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name ...
      Caused by: java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting 'identifier' at character position 0
      ^
      at org.aspectj.weaver.tools.PointcutParser.resolvePoi ntcutExpression(PointcutParser.java:316)

      Spring wiring configuration:
      Code:
      @Configuration
      @EnableAspectJAutoProxy
      public class LoggingAspectTestConfig {	
      //...
      	@Bean
          public LoggingAspect loggingAspect() {
              return new LoggingAspect();
          }
      	@Bean
      	public Module1LoggingPointcuts module1LoggingPointcuts() {
      		return new Module1LoggingPointcuts();
      	}
      }

      Comment

      Working...
      X