离开方法时使用拦截器

时间:2015-10-23 08:19:58

标签: java java-ee interceptor

在我的 Java EE 程序中,我想使用 Interceptor 进行日志记录。当我输入方法时,它很容易使用:

注释:

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({ METHOD, TYPE })
public @interface Logged {

}

拦截器:

@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    private Logger logger;

    @AroundInvoke
    public Object logMethodEntry(InvocationContext invocationContext) throws Exception {

        logger.info("Entering method: "
            + invocationContext.getMethod().getName() + " in class "
            + invocationContext.getMethod().getDeclaringClass().getName());

        return invocationContext.proceed();

    }
}

我的班级使用拦截器:

public class MyClass {

    @Logged
    public void MyMethod() {
        // do something
    }

}

但是现在我想在离开 MyMethod 时做同样的事情。这可能吗?

2 个答案:

答案 0 :(得分:3)

AroundInvoke并不意味着特意进入 - 它意味着你把它挂起来"围绕调用&#34 ;;它的名字恰如其分。那个proceed()调用就是你用拦截器包装的实际方法调用。因此,您当前在proceed()调用之前进行日志记录 - 如果在proceed()调用之后添加日志,那么就是离开方法调用的时间点。

@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {

  private static final long serialVersionUID = 1L;

  @Inject
  private Logger logger;

  @AroundInvoke
  public Object logMethodCall(InvocationContext invocationContext) throws Exception {

        logger.info("Entering method: "
          + invocationContext.getMethod().getName() + " in class "
          + invocationContext.getMethod().getDeclaringClass().getName());

        Object ret = invocationContext.proceed();

        logger.info("Left method: "
          + invocationContext.getMethod().getName() + " in class "
          + invocationContext.getMethod().getDeclaringClass().getName());

        return ret;
  }
}

答案 1 :(得分:3)

@Gimby的答案几乎是正确的。他的解决方案中缺少的是异常处理。如果发生异常,则永远不会记录“Left方法”。

建议解决方案:

@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {

  private static final long serialVersionUID = 1L;

  @Inject
  private Logger logger;

  @AroundInvoke
  public Object logMethodCall(InvocationContext invocationContext) throws Exception {

        Object ret = null;
        logger.info("Entering method: "
          + invocationContext.getMethod().getName() + " in class "
          + invocationContext.getMethod().getDeclaringClass().getName());

        try {

           ret = invocationContext.proceed();

        } catch(Exception e) {

            throw e;

        } finally  {

           logger.info("Left method: "
             + invocationContext.getMethod().getName() + " in class "
             + invocationContext.getMethod().getDeclaringClass().getName());

        }

        return ret;
  }
}