Bgvv1983
Bgvv1983

Reputation: 1256

How to resolve from an Injeactable its caller class?

Say I a class A which injects aclass B. In class B I need implicitly to get hold of the class which has inject class B. So in this case this would be class A.

Does anyone know how to receive this in a robust way?

Tried this as well but this gives me Logger not its caller.

Something like

@Stateless
@Dependent
public class Logger {

@Inject
InjectionPoint ip;

@Asynchronous
public void doSomething(){
   ip.getMember().getDeclaringClass().getName()
 }
}

Upvotes: 1

Views: 486

Answers (2)

Siliarus
Siliarus

Reputation: 6753

If we are talking about @Dependent scoped beans, there is a way documented in the CDI spec.

The general idea is that CDI allows you to inject an object called InjectionPoint and from that you can get information on what bean injected this bean.

Here is a short snippet:

@Dependent //if you don't declare any scope, it's @Dependent by default
public class MyBean {
  @Inject
  InjectionPoint ip;

  public void doStuff() {
    // gives you the name of declaring class
    ip.getMember().getDeclaringClass().getName(); 
  }
}

Alternatively, you might use a constructor injection in your bean to handle this during bean creation. It might be closer to what you aim for perhaps:

@Dependent //if you don't declare any scope, it's @Dependent by default
public class MyAnotherBean {
  public MyAnotherBean(InjectionPoint ip) {
    // CDI will inject InjectionPoint automatically
    ip.getMember().getDeclaringClass().getName(); 
  }
}

Again, note that this works for @Dependent only! Why? Well, because @Dependent creates new instance per injection point and uses no proxy. Therefore you also know precisely who are you creating this instance for. Other scopes, such as @RequestScoped, @SessionScoped and so forth, do use a proxy and therefore you are only instantiating one object in CDI and then passing proxies whenever injection is requested.

Upvotes: 3

Bgvv1983
Bgvv1983

Reputation: 1256

Seems that I found a solution.

Made a HelperClass. which containst an @AroundInvoke method.

@AroundInvoke
public Object injectMap(InvocationContext ic) throws Exception {
    StackTraceElement element = Thread.currentThread().getStackTrace()[CLASS_NAME_ELEMENT];
    return ic.proceed();
}

In Class A I annotate the method which needs Uses the injectable class B with:

@Interceptors(ContextHelper.class)

This seems to work for what I want.

Upvotes: 1

Related Questions