用AOP覆盖 @override

huangapple go评论70阅读模式
英文:

Override @override with AOP

问题

这是我的OverrideInterceptor:

@Singleton
@Slf4j
public class OverrideInterceptor implements MethodInterceptor<Object, Object> {

  @Override
  public Object intercept(MethodInvocationContext<Object, Object> context) {
    String prettyMethod = context.getDeclaringType().getSimpleName() + "." + context.getName();
    log.debug("{} with params {}", prettyMethod, context.getParameterValueMap());
    long start = System.nanoTime();
    Object result = context.proceed();
    long end = System.nanoTime() - start;
    log.debug("Execution of " + prettyMethod + " took: " + (end/1000) + "ms.");
    return result;
  }
}

以及我的注解:

@Documented
@Retention(RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Around
@Type(OverrideInterceptor.class)
public @interface Override {

}

这两个类都位于包中:package com.time.infrastructure.config;

我在包下的地方使用了这个@Override注解:com.time.infrastructure.db、com.time.infrastructure.rest、com.time.application.repository,等等。

英文:

I'm giving AOP a try for the first time. I want to do AOP on the @Override notation to write logs. It seems to be almost working but:

  1. I have to import my own Override class in every class. Is this normal? I thought that it would magically go through my @Override decorator first and then through the Java one.
  2. I have this very weird behavior where depending on the endpoint that I call first, it keeps working after or it only works for this one endpoint. Say, I have /a and /b, if I call /b first, it shows my logs, then I'll call /a and it won't show anything, if after that I call /b it will show logs. However, if I call /a first, it works, then I call /b and it works, and it just keeps working for all of them. It makes no sense to me.

This is my OverrideInterceptor:

@Slf4j
public class OverrideInterceptor implements MethodInterceptor&lt;Object, Object&gt; {

  @Override
  public Object intercept(MethodInvocationContext&lt;Object, Object&gt; context) {
    String prettyMethod = context.getDeclaringType().getSimpleName() + &quot;.&quot; + context.getName();
    log.debug(&quot;{} with params {}&quot;, prettyMethod, context.getParameterValueMap());
    long start = System.nanoTime();
    Object result = context.proceed();
    long end = System.nanoTime() - start;
    log.debug(&quot;Execution of &quot; + prettyMethod + &quot; took: &quot; + (end/1000) + &quot;ms.&quot;);
    return result;
  }
}

And my annotation:

@Documented
@Retention(RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Around
@Type(OverrideInterceptor.class)
public @interface Override {

}

Both classes are in the package: package com.time.infrastructure.config;

And I'm using this @Override annotation in packages under com.time.infrastructure.db, com.time.infrastructure.rest, com.time.application.repository, etc.

答案1

得分: 1

关于第一个点:内置的 @Override 注解是一个普通的 @interface - 它位于 java.lang 包中。你在这里所做的是在 com.time.infrastructure.config 包中创建了一个名为 Override 的自定义注解,它与 java.lang.Override 没有任何关系。从这个意义上说,它是“正常”的,但它可能并不像你想的那样起作用。遗憾的是,在Java中你不能对注解进行子类型化。

英文:

For point 1: The built-in @Override annotation is a normal @interface - it resides in the java.lang package. What you've done here is that you've created a custom annotation with the name Override in the package com.time.infrastructure.config, which has nothing to do with java.lang.Override. So in that sense, it's "normal", but it's probably not doing what you think. You can't subtype annotations in Java, unfortunately.

huangapple
  • 本文由 发表于 2020年10月5日 19:18:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/64207588.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定