Jason White
Jason White

Reputation: 4792

CDI constructor-based injection with @Resource

Is it possible to do a constructor-based CDI injection of a @Resource type of instance?

I have the following class:

class MyClass {

  @Resource
  private ManagedExecutorService executorService;

  @Inject
  private MyService myservice;

}

I would like to convert it into something like this:

class MyClass {

  private final ManagedExecutorService executorService;
  private final MyService myservice;

  @Inject
  MyClass(ManagedExecutorService executorService, MyService myService) 
  {
    this.executorService = executorService;
    this.myService = myService;
  }

}

This would make the class immutable and easier to unit test. The problem is that since the executorService needs to be obtained via a @Resource annotation, it doesn't seem to be injectable via the constructor.

Upvotes: 3

Views: 1117

Answers (1)

Jason White
Jason White

Reputation: 4792

Here is what I ended up doing - I created a producer class to managed the resource object:

public class ExecutorServiceProducer {

    @Resource
    private ManagedExecutorService managedExecutorService;

    @Produces
    @Managed
    public ExecutorService createManagedExecutorService() {
        return managedExecutorService;
    }

}

and I created this custom annotation:

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Managed {
}

and then I was able to annotate my class as follows:

class MyClass {

  private final ExecutorService executorService;
  private final MyService myservice;

  @Inject
  MyClass(@Managed ExecutorService executorService, MyService myService) 
  {
    this.executorService = executorService;
    this.myService = myService;
  }

}

This way I can unit test the class by providing my own ExecutorService (non-container managed) instance.

Upvotes: 3

Related Questions