Search code examples
javajakarta-eecdijboss-weldweld

CDI Extensions - Add Interceptors in ProcessAnnotatedType phase


I am trying to add an interceptor programatically. The interceptor is called LogginInterceptor and just logs the name of method it runs on. When using it with annotation @Interceptors(LogginInterceptor.class) on a method, everything works fine.

I am however trying to create CDI Extension that adds this @Interceptors(LogginInterceptor) annotation programatically to every method of a certain class (to be simple). So, try it, I've created class Hello with few methods. When these methods are annotated manually, the LogginInterceptor works and prints the name of the method. However, my code to add this programatically via CDI extensions does not work.

    <T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> pat) {

    if (pat.getAnnotatedType().getJavaClass().equals(Hello.class)) {
        Logger.getLogger("").info("Initial annotations: " + pat.getAnnotatedType().getAnnotations());


        Map<String, Class[]> values = new HashMap<>();
        Class[] classes = {LoggingInterceptor.class};
        values.put("value", classes);
        Interceptors interceptors = AnnotationInstanceProvider.of(Interceptors.class, values);
        AnnotatedTypeBuilder<T> builder = new AnnotatedTypeBuilder<T>().readFromType(pat.getAnnotatedType());

        pat.getAnnotatedType().getMethods().forEach(method -> {
            builder.addToMethod(method, interceptors);
        });

        pat.setAnnotatedType(builder.create());
        Logger.getLogger("").info("Ending annotations: " + pat.getAnnotatedType().getAnnotations());
    }
}

I am using Apache Deltaspike for AnnotationInstanceProvider and AnnotatedTypeBuilder. The annotation is created, as well as the wrapping AnnotatedType. However, the interceptor is not working.

I use WildFly 9.

PS: I also noticed that interceptor bindings do not work for me. Only @Interceptors annotation works.

Thank you kindly for any advice.


Solution

  • It's better to add the annotation-instance to the whole bean via AnnotatedTypeBuilder#addToClass. Don't forget to enable the interceptor per archive (via beans.xml) or globally via @javax.annotation.Priority. You can even create an instance of it dynamically and add it to your interceptor-implementation class (which is annotated with @Interceptor). Without that your @InterceptorBinding can't work at all.