Ankur Mahajan
Ankur Mahajan

Reputation: 3596

AOP based logging in Guice

I am trying to implement AOP based logging in Google - Guice. I have used MethodInterceptor for this but it doesn't work. I have used same in Spring by defining point-cuts. Everything is working fine there.

Spring Code for AOP based logging -

@Aspect
public class LoggingAspect {

 private static Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

   @Around("requiredLog()")
   public Object bentoBoxAround(ProceedingJoinPoint proceedingJoinPoint) {

      Object returnValue = null;
      try {

          logger.info("Entered into the method -> " + proceedingJoinPoint.getSignature().toShortString()
                  + " and input arguments are -> " + Arrays.asList(proceedingJoinPoint.getArgs()));
          returnValue = proceedingJoinPoint.proceed();
          logger.info("Method Execution over !! " + proceedingJoinPoint.getSignature().toShortString());
      } catch (Throwable e) {
          logger.error("Method has an exception " + e.getMessage());
      }
      return returnValue;
   }

   @Pointcut("within(org.cal.bento..*)")
   public void allRequiredPakageLog() {
   }

 }

From above code we can log all the class and method executions inside the org.cal.bento.* package.

Guice code for AOP based logging -

public class GuiceLoggingInterceptor implements MethodInterceptor {

 private static Logger logger = LoggerFactory
 .getLogger(GuiceLoggingInterceptor.class);

  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    Object returnValue = null;
    try {
        logger.info("GUICE - Entered into the method -> " + invocation.getMethod().getName()
                    + " and input arguments are -> " + Arrays.asList(invocation.getArguments()));
        returnValue = invocation.proceed();
        logger.info("Method Execution over !! " + invocation.getMethod().getName());
    } catch (Throwable e) {
        logger.error("GUICE - Method has an exception " + e.getMessage());
    }
    return returnValue;
  }
}

Binding Class -

public class GuiceAopModule extends AbstractModule {

  @Override
  protected void configure() {
      bindInterceptor(Matchers.any(), Matchers.any(), new GuiceLoggingInterceptor());
  }
}

Can we do similar in Guice for logging (by defining only one Aspect based class for whole logging system). I don't want to modify every class.

Refered Tutorial - https://schakrap.wordpress.com/2009/07/30/method-entry-exit-logging-in-guice-with-aop/

Any help would be highly appreciated.

Upvotes: 2

Views: 5210

Answers (1)

pandaadb
pandaadb

Reputation: 6456

Your issue appears to be that you are not using guice for creation. From the guice docs:

This approach imposes limits on what classes and methods can be intercepted:

[...]

Instances must be created by Guice by an @Inject-annotated or no-argument constructor It is not possible to use method interception on instances that aren't constructed by Guice.

So this means, that because your instances are created by spring and likely added to guice, guice has no chance of proxying those classes for interception.

Source:

https://github.com/google/guice/wiki/AOP

Edit:

what you can do (as workaround) to be able to make this work would be:

  1. Spring creates your instances.

  2. Put them into guice

  3. Create a delegate object that is created by Guice and inject the bean of (1) into the wrapper.

  4. Use the wrapper instead of the object in 1 and then the methods will get intercepted.

Upvotes: 5

Related Questions