CDI + controlled concurrency in Java EE 7

I am implementing a service with an application scope (for further implementation in a JAX-RS / JAX-WS service or servlet, it does not matter), which would spawn some processing through a ManagedExecutorService or ManagedThreadFactory. Internal processing code (Runnable instance), I want to use nested resources such as EntityManager, DataSource and web service links. The first solution was 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 is displayed as null. Well, this is because the MyTask instance is not a managed bean, that is, it was not created by the DI container, so the injection is not available to it. Allows you to modify the direct creation of an instance of a context 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()); } } 

It works as desired. But is this the right / best way to achieve what I want? Typically, the problem is how to create injected / managed instances on demand at runtime. In addition, in the latter case, I have no way to pass any parameter to the MyTask constructor - is this even possible or do I need to enter the MyTask.setParam () method to configure the MyTask instance?

+6
source share
1 answer

Passing parameters to the constructor is prohibited by the CDI specification - the container can only call the default constructor or constructor, which is annotated using @Inject , see CDI Specification - 3.1 0.1. What Java classes are managed by beans . So yes, you will need to enter the setter here.

+1
source

Source: https://habr.com/ru/post/958032/


All Articles