Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CDI + managed concurrency in Java EE 7

I'm implementing an application-scoped service (to be further injected into JAX-RS/JAX-WS service or a servlet, does not matter) which would spawn some processing via ManagedExecutorService or ManagedThreadFactory. Inside processing code (a Runnable instance), I want to use injected resources like EntityManager, DataSource and web service references. The first solution was like this:

@ApplicationScoped
class MyService {

 @Resource private ManagedExecutorService mes;

 public void request(String param) {
  mes.submit(new MyTask(param));
 }

}

class MyTask implements Runnable {
 // constructor skipped
 @Resource private DataSource ds;

 public void run() {
  // do processing
 }

}

Inside MyTask.run(), the ds field appears to be null. Okay, this happens because the MyTask instance is not a managed bean, i.e. it wasn't created by a DI container, so injection is not available for it. Let's change direct instantiation to contextual instance:

@ApplicationScoped
class MyService {

 @Resource ManagedExecutorService mes;
 @Inject private Instance<MyTask> instance;

 public void request(String param) { // <- no way to pass param to MyTask()!
  mes.submit(instance.get());
 }

}

This works as desired. But is this the right/best way to achieve what I want? Generally, the problem is, how do I create injected/managed instances on demand at runtime. Furthermore, in the latter case I have no ability to pass any parameter to MyTask constructor - is that possible at all, or do I have to introduce MyTask.setParam() method to configure an instance of MyTask?

like image 724
Dimitri Avatar asked Nov 13 '13 23:11

Dimitri


People also ask

Which concurrency mechanism is provided by Java EE?

Concurrency Utilities for Java EE is an asynchronous programming model that enables you to submit or schedule tasks to run in parallel, create threads that inherit Java EE context, and transfer Java EE context to invocation of interfaces such as asynchronous callbacks.

How does CDI work java?

CDI (Contexts and Dependency Injection) is a standard dependency injection framework included in Java EE 6 and higher. It allows us to manage the lifecycle of stateful components via domain-specific lifecycle contexts and inject components (services) into client objects in a type-safe way.

What is CDI in spring?

CDI stands for "context and dependency injection", while Spring is a complete ecosystem around a dependency injection container.

What is Weld CDI?

Weld is the reference implementation of CDI: Contexts and Dependency Injection for the Java EE Platform - a JCP standard for dependency injection and contextual lifecycle management and one of the most important and popular parts of the Java EE.


1 Answers

Passing of parameters to constructor is forbidden by CDI specification - container can only call default constructor or constructor which is annotated with @Inject, see CDI spec - 3.1.1. Which Java classes are managed beans. So yes, you will have to introduce setter here.

like image 117
Petr Mensik Avatar answered Sep 29 '22 14:09

Petr Mensik