代码之家  ›  专栏  ›  技术社区  ›  Serhii

如何从父方法获取注释?

  •  3
  • Serhii  · 技术社区  · 7 年前

    我有一个界面:

    public interface JustToCheckInterface {
    
        @MyCheck(feature = "occurrence-logging")
        void log();
    
        void log2();
    
        @MyCheck(feature = "check-logging")
        void log3();
    }
    

    和实施:

    @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");
        }
    }
    

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

    @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;
        }
    }
    

    方法拦截器

    @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;
        }
    }
    

    log() log3() .

    对于我来说,有两个潜在的解决方案:

    不幸的是,我在这两方面都不强。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Dean Xu    7 年前

    您可以遍历所有超类和接口的超方法来查找注释。但是您可能会发现多个注释,因为该方法可能在多个类或接口中声明。

    以下是我的示例代码:

    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() {
    
        }
      }
    }
    

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

    ReflectUtil ,你可以找到它 here