Search code examples
interceptorquarkus

Quarkus extension - How to have an interceptor working on beans provided by the extension itself


I'm working on a Quarkus extension that provides an interceptor (and its annotation) to add some retry logic around business methods this extension offers. Nothing new in there, and this is working when i annotate a public method of a bean in an application that uses this extension.

But the extension also provides some @ApplicationScoped beans that are also annotated, but the interceptor is not intercepting any of these.

Seems like an interceptor does not check / apply on the extension itself.

I would like to know if this is an intended behavior, or an issue in my extension setup, and if so how to fix it. Could not find anything about this in the documentation, but there is so much dos that i may have missed something.

Any idea about this ?


Solution

  • I finally found a way to make this work.

    I was using a producer bean pattern to produce my beam as an @ApplicationScoped bean inside the extension.

    @ApplicationScoped
    public class ProxyProducer {
    
      @Produces
      @ApplicationScoped
      public BeanA setUpBean(ExtensionConfig config) 
      {
    
        return new BeamsClientProxy(new InternalBean(config.prop1, config.prop2));
      }
    
    }
    

    with the following BeanA class (just an example)

    public class BeanA {
    
      private final InternalBean innerBean;
    
      public BeanA(final InternalBean innerBean) {
        this.innerBean = innerBean;
      }
    
      @MyInterceptedAnnotation
      public void doSomething() {
      }
    }
    

    Due to this setup, the bean is not considered by the interceptor (i guess because it's produced only the first time it's used / injected somewhere else)

    Removing the producer pattern and annotating directly the BeanA fixed the issue. Example:

    @ApplicationScoped
    public class BeanA {
    
      private final InternalBean innerBean;
    
      public BeanA(final ExtensionConfig config) {
        this.innerBean = new InternalBean(config.prop1, config.prop2);
      }
    
      @MyInterceptedAnnotation
      public void doSomething() {
      }
    }
    

    with of course adding the following lines to register the bean directly on the extension processor:

    @BuildStep
    AdditionalBeanBuildItem proxyProducer() {
        return AdditionalBeanBuildItem.unremovableOf(BeanA.class);
    }
    

    As a conclusion:

    • Changing the bean implementation to avoid the producer-based bean use case solved my issue (please refers to Ladicek comment below)

    Edit: As Ladicek explained, Quarkus doesn't support interception on producer-based beans.