简体   繁体   English

如何从父方法获取注释?

[英]How to get annotations from parent method?

I have an interface:我有一个界面:

public interface JustToCheckInterface {

    @MyCheck(feature = "occurrence-logging")
    void log();

    void log2();

    @MyCheck(feature = "check-logging")
    void log3();
}

and implementation:和实施:

@Component
public class JustToCheck implements JustToCheckInterface {

    public void log() {
        System.out.println("hello");
    }

    @MyCheck(feature = "check-no-logging")
    public void log2() {
        System.out.println("hello2");
    }

    public void log3() {
        System.out.println("hello3");
    }
}

I've created annotation (the one is used in my interface and in spring component):我已经创建了注释(在我的界面和 spring 组件中使用了该注释):

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Documented
public @interface MyCheck {

    @Required
    String feature();
}

and advisor:和顾问:

@Component
public class MyAdvisor extends AbstractPointcutAdvisor {
    @Autowired
    private MyMethodInterceptor myMethodInterceptor;
    private final StaticMethodMatcherPointcut pointcut = new
            StaticMethodMatcherPointcut() {
                @Override
                public boolean matches(Method method, Class<?> targetClass) {
                    return method.isAnnotationPresent(MyCheck.class);
                }
            };

    @Override
    public Pointcut getPointcut() {
        return pointcut;
    }

    @Override
    public Advice getAdvice() {
        return myMethodInterceptor;
    }
}

method interceptor方法拦截器

@Component
public class MyMethodInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        MyCheck annotation = methodInvocation.getMethod().getAnnotation(MyCheck.class);
        if (mySpecialCheck(annotation.feature())) {
            return methodInvocation.proceed();
        }
        return null;
    }
}

It seems almost work.似乎几乎可以工作。 It works for object if the called method (that overrides parent interface) has correspond annotation.如果被调用的方法(覆盖父接口)具有相应的注释,则它适用于对象。 But it does not work for methods which overrides interface without annotation in case the interface methods has the annotation.但它不适用于覆盖没有注释的接口的方法,以防接口方法有注释。 See methods log() and log3() .请参阅方法log()log3()

As for me there are two potential candidates into solution:至于我,有两个潜在的候选解决方案:

  • reflection solution (get superMethods and annotations from super);反射解决方案(从 super 获取 superMethods 和 annotations);
  • interceptor solution (improve one).拦截器解决方案(改进一)。

unfortunately i'm not strong in both of them.不幸的是,我在这两个方面都不强。

You can traverse all the super classes and interfaces' super methods to find the annotation.你可以遍历所有的超类和接口的超方法来找到注解。 But you may find more than one annotation because the method may declared in several classes or interfaces.但是您可能会发现不止一个注解,因为该方法可能在多个类或接口中声明。

Here is my sample code:这是我的示例代码:

public class Q46553516 {
  public static void main(String[] args) throws Exception {
    // the input method
    Method method = ClassB.class.getMethod("func");
    // get the annotation value
    Class<?> clz = method.getDeclaringClass();
    List<Anno> collect = Stream.concat(
        Stream.of(clz),
        Stream.concat(
            Stream.of(ReflectUtil.getAllSuperClasses(clz)),
            Stream.of(ReflectUtil.getAllInterfaces(clz))))
        .map(c -> {
          try {
            return c.getMethod(method.getName(), method.getParameterTypes());
          } catch (Exception e) {
            return null;
          }
        })
        .filter(m -> m != null)
        .map(m -> m.getAnnotation(Anno.class))
        .filter(a -> a != null)
        .collect(Collectors.toList());
    collect.forEach(System.out::println);
  }

  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.METHOD)
  @Documented
  @Inherited
  public @interface Anno {
    String value();
  }

  static interface Inter {
    @Anno("Inter")
    void func();
  }

  static class ClassA implements Inter {
    @Override
    @Anno("ClassA")
    public void func() {

    }
  }

  static class ClassB extends ClassA {
    @Override
    public void func() {

    }
  }
}

and output:和输出:

@xdean.stackoverflow.java.reflection.Q46553516$MyCheck(feature=ClassA)
@xdean.stackoverflow.java.reflection.Q46553516$MyCheck(feature=Inter)

I used my utility ReflectUtil , you can find it here我使用了我的实用程序ReflectUtil ,你可以在这里找到它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM