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?
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.
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.
CDI stands for "context and dependency injection", while Spring is a complete ecosystem around a dependency injection container.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With