pal*_*int 6 java dependency-injection cdi jboss-weld
我有一个ServiceJava SE应用程序(没有任何应用程序服务器),它创建Algorithm实例并运行它们.
Algorithm实例都需要一个新的(单独的)ActionExecutor和一个新的(单独的)AlgorithmState.ActionExecutor还需要一个AlgorithmState实例,这个实例必须和Algorithmgets一样.我怎样才能用CDI实现这一目标?我已经尝试过构造函数注入和@New两个参数,Algorithm但我想这不是我想要的.
Service 类:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Algorithm 类:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
ActionExecutor 类:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
AlgorithmState 类:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
还有一个ServiceMain测试类:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
目前它打印以下内容:
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
Run Code Online (Sandbox Code Playgroud)
我需要的是,stateId并且executor->stateId是相同的:
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
Run Code Online (Sandbox Code Playgroud)
编辑:
目前我AlgorithmState从中得到了AlgorithmExecutor它但它弄乱了模型,我想避免这种情况.
首先,@New限定符被替换为@Dependant范围,无论如何它都是默认范围。我想它在 CDI 1.1 中被改变了,因为它造成了混乱。另外,@New是一个限定符,而不是范围,并且来自一个可用于多种目的的单独标准(我认为@New任何标准都没有真正使用它)。
看来您想使用@ProducesinAlgorithmState而不是@Inject. 查看有关该主题的 Weld 文档以了解更多详细信息。您可能想要创建一个特定的作用域类型,如下所示:
@ScopeType
@Retention(RUNTIME)
@Target({TYPE, METHOD, CONSTRUCTOR})
public @interface AlgorithmScoped {}
Run Code Online (Sandbox Code Playgroud)
然后你可以修改AlgorithmState构造函数:
@Produces @AlgorithmScoped
public AlgorithmState() {
// ...
}
Run Code Online (Sandbox Code Playgroud)
将该范围添加到AlgorithmExecutor,然后也添加到Algorithm。我认为你不应该尝试AlgorithmState注入Algorithm; 从实例中获取它AlgorithmExecutor!事实上,如果你这样做,那么简而言之应该可以解决整个问题。
| 归档时间: |
|
| 查看次数: |
851 次 |
| 最近记录: |