mardi 3 octobre 2017

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):

@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().

As for me there are two potential candidates into solution:

  • reflection solution (get superMethods and annotations from super);
  • interceptor solution (improve one).

unfortunately i'm not strong in both of them.





Aucun commentaire:

Enregistrer un commentaire