How to specify interceptor at inject time

1.9k views Asked by At

I have some beans for which, in specific injections, I want to add a given interceptor.

I was naïvely thinking there was something like a @Interceptors annotation that could allow me to write

private @Interceptors(Logging.class, Connection.class) @Inject MyBean instance;

Unfortunatly, Weld documentation clearly states the opposite.

So, how could I inject an intercepted version of my bean ? Is it possible using a cdi Instance object ?

EDIT

Although LightGuard's answser is really relevant, it doesn't totally answser my question, so let me rephrase it.

I want to have an annotation that triggers some kind of method call event sending. For that, I created a CDI Interceptor, complete with its own interceptor binding (let's say interceptor is called SenderInterceptor, and the binding is called SenderBinding). What I want now is to add a CDI qualifier (let's call it SenderQualifier) that, when used for an injection, installs SenderInterceptor.

To be more clear, I want the following code to use SenderInterceptor

/* calling any method of that bean should trigger an event */
private @Inject @SenderQualifier MyBean aBean;

while this one doesn't

private @Inject MyBean aBean;

What I tried so far was

  • detecting fields requiring those injections using reflections library (that works)
  • create using seam solder an AnnotatedType from bean class (during the BeforeBeanDiscovery event) (the type is created, but not really distinguishable from the initial one) and giving that AnnotatedType the interceptor binding annotation.
  • create using seam solder (again) a Bean from generated AnnotatedType, and giving it the required qualifier annotation

All seems to worrk, except it's the original bean which gets injected.

I could of course replace original one with intercepted one, but there are some cases where such interception is not required, so I have to keep both AnnotatedType refering the same concrete type. I was thinking I coulld do that in CDI, but it doesn't seems to work (as original type is never replaced by intercepted one).

2

There are 2 answers

6
LightGuard On BEST ANSWER

What you would need to do:

  1. Add the interceptor to beans.xml so it's activated
  2. Create an extension to add the interceptor binding or the interceptor annotation to the type in ProcessAnnotatedType life cycle event. You'll need to call getAnnotatedType, add the annotation(s) then call setAnnotatedType. I strongly recommend looking at Seam Solder or Apache DeltaSpike project for the AnnotatedTypeBuilder to make this easier.
1
mgaert On

Possibly, you could try @Inject MyInterceptedBean instance;, where the interceptors are listed with the MyInterceptedBean?

(Caveat: this does not look right, though, using inheritance for types that only differ in annotations ... probably acceptable when it's always the two stated same annotations and not different annotations in each case.)