I have a Service in a Java SE application (without an application server) that creates Algorithm instances and runs them.
- Each
Algorithm instance needs a new (separate) ActionExecutor and a new (separate) AlgorithmState . ActionExecutor also needs an AlgorithmState instance, and this instance should be the same as the Algorithm receives.
How can I achieve this using CDI? I tried the constructor injection and @New on both Algorithm parameters, but I think this is not what I want.
Service class:
import java.util.ArrayList; import java.util.List; import javax.enterprise.inject.Instance; import javax.inject.Inject; public class Service { @Inject private Instance<Algorithm> algorithmInstance; public void run() { final List<Algorithm> algorithms = new ArrayList<>(); for (int i = 0; i < 3; i++) { final Algorithm algorithm = algorithmInstance.get(); algorithms.add(algorithm); } for (final Algorithm algorithm: algorithms) { algorithm.doSomething(); } } }
Algorithm class:
import java.util.concurrent.atomic.AtomicInteger; import javax.enterprise.inject.New; import javax.inject.Inject; public class Algorithm { private static final AtomicInteger counter = new AtomicInteger(100); private final ActionExecutor actionExecutor; private final AlgorithmState algorithmState; private final int id; @Inject public Algorithm(@New final ActionExecutor actionExecutor, @New final AlgorithmState algorithmState) { this.actionExecutor = actionExecutor; this.algorithmState = algorithmState; id = counter.incrementAndGet(); System.out.println("algorithm ctor#" + id); } public void doSomething() { System.out.printf("do something, algorithm id: #%d: executor id%sd, stateId: %d, executor->stateId: %d%n", id, actionExecutor.getId(), algorithmState.getId(), actionExecutor.getAlgorithmStateId()); } }
ActionExecutor class:
import java.util.concurrent.atomic.AtomicInteger; import javax.inject.Inject; public class ActionExecutor { private static AtomicInteger counter = new AtomicInteger(200); private final AlgorithmState algorithmState; private final int id; @Inject public ActionExecutor(final AlgorithmState algorithmState) { this.algorithmState = algorithmState; id = counter.incrementAndGet(); } public int getId() { return id; } public int getAlgorithmStateId() { return algorithmState.getId(); } }
AlgorithmState class:
import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.PostConstruct; import javax.inject.Inject; public class AlgorithmState { private static final AtomicInteger counter = new AtomicInteger(300); private final int id; @Inject public AlgorithmState() { id = counter.incrementAndGet(); } @PostConstruct public void start() { System.out.println("state start#" + id); } public int getId() { return id; } }
And the ServiceMain class for testing:
import java.util.List; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.jboss.weld.environment.se.bindings.Parameters; import org.jboss.weld.environment.se.events.ContainerInitialized; public class ServiceMain { @Inject private Service service; public void printHello( @Observes final ContainerInitialized event, @Parameters final List<String> parameters) { System.out.println("ServiceMain:" + service); service.run(); } public static void main(final String[] args) { org.jboss.weld.environment.se.StartMain.main(args); } }
He is currently printing the following:
do something, algorithm id: #101: executor id201d, stateId: 302, executor->stateId: 301 do something, algorithm id: #102: executor id202d, stateId: 304, executor->stateId: 303 do something, algorithm id: #103: executor id203d, stateId: 306, executor->stateId: 305
I need stateId and executor->stateId be the same:
do something, algorithm id: #101: executor id201d, stateId: 301, executor->stateId: 301 do something, algorithm id: #102: executor id202d, stateId: 302, executor->stateId: 302 do something, algorithm id: #103: executor id203d, stateId: 303, executor->stateId: 303
change
I am currently getting AlgorithmState from AlgorithmExecutor , but it messed up the model, I would like to avoid it.