gpt4 book ai didi

java - 如何以编程方式查找和注入(inject)限定符包含类名的 CDI 托管 bean

转载 作者:行者123 更新时间:2023-11-30 11:05:47 24 4
gpt4 key购买 nike

我正在尝试以编程方式查找并注入(inject)一个 CDI 托管 bean,其中限定符包含一个类的名称(不是我要注入(inject)的类),但是我遇到的问题是我正在使用的代码查找正确的 bean 总是返回 null .

我要注入(inject)的 bean 带有一个名为 @CQRSCommandHandler 的自定义注解。其中包含用作限定符的类的名称,bean 还实现了一个名为 CommandHandler 的接口(interface).我正在使用限定符的类实现了接口(interface) Command .

基于我对 CDI 的有限了解,我相信为了以编程方式查找已使用 @CQRSCommandHandler 限定的正确 bean注释,我需要扩展 AnnotationLiteral然后我可以使用 Instance选择 bean。

@CQRSCommandHandler 的代码注释如下:

@Qualifier
@Documented
@Retention(value= RetentionPolicy.RUNTIME)
public @interface CQRSCommandHandler {
Class<? extends Command> command();
}

扩展AnnotationLiteral的代码如下:

public class CQRSCommandHandlerQualifier extends AnnotationLiteral<CQRSCommandHandler> implements CQRSCommandHandler {

private static final long serialVersionUID = 1L;
private final Class<? extends Command> command;

public CQRSCommandHandlerQualifier(Class<? extends Command> command) {
this.command = command;
}

@Override
public Class<? extends Command> command() {
return command;
}

}

我用来使用 CDI 查找正确 bean 的代码如下:

@Inject
@Any
private Instance<CommandHandler> commandHandlerInstance;

private CommandHandler findCommandHandlerFor(Command command) {

CommandHandler commandHandler = commandHandlerInstance.select(new CQRSCommandHandlerQualifier(command.getClass())).get(); //This always returns null
return commandHandler;
}

尽管在谷歌上搜索了很多小时,我还是无法弄清楚为什么 commandHandlerInstance.select(new CQRSCommandHandlerQualifier(command.getClass())).get();不返回已用 @CQRSCommandHandler (command = MyCommand.class) 注释的 bean 实例bean 实现了 CommandHandler接口(interface)和MyCommand.class实现接口(interface) Command .

这是以编程方式查找和注入(inject)限定符包含类名的 CDI 托管 bean 的正确方法吗?如果是这样,我上面的代码哪里出错了?如果不是,实现相同最终结果的最佳方法是什么?


更新

以下代码是我尝试查找的 bean 的示例实现:

@CQRSCommandHandler(command = CreateToDoItemCommand.class)
public class CreateToDoItemCommandHandler implements CommandHandler {

@Override
public <R> Object handle(Command command) {
System.out.println("This is the CreateToDoItemCommandHandler");
return null;
}
}

以下代码是CommandHandler的接口(interface):

public interface CommandHandler {

public <R> Object handle(Command command);

}

以下代码是我在限定符中用作参数的类的示例:

public class CreateToDoItemCommand implements Command {

private String todoId;
private String description;

public CreateToDoItemCommand(String todoId, String description) {
this.todoId = todoId;
this.description = description;
}

public String getTodoId() {
return todoId;
}

public String getDescription() {
return description;
}

}

我已经在 Eclipse 中单步执行了代码,似乎 Instance commandHandlerInstance 的对象是null .


更新 2

正如@redge 所建议的,我将实例化的每个步骤分开到单独的一行中,如下所示:

private CommandHandler findCommandHandlerFor(Command command) {
CQRSCommandHandlerQualifier qualifier = new CQRSCommandHandlerQualifier(command.getClass());
Instance<CommandHandler> instance = commandHandlerInstance.select(qualifier);
CommandHandler commandHandler = instance.get();
return commandHandler;
}

问题似乎出在这行代码 Instance<CommandHandler> instance = commandHandlerInstance.select(qualifier);其中 NullPointerException被抛出大概是因为 Instance对象 commandHandlerInstancenull

我在 Weld 2.0.0 SP1 附带的 GlashFish 4 上运行此代码,但我也刚刚尝试在 GlashFish 4.1 上运行相同的代码并安装了 Weld 版本 2.2.10.SP1,这是来自Maven Central 但出现同样的问题。

最佳答案

您有 GlassFish 4.1。我怀疑您是否有 beans.xml 文件,如果有,应该根据您当前的设置将其标记为 bean-discovery-mode="all"。如果你不这样做,或者你使用 bean-discovery-mode="annotated" 那么你需要为你的每个命令添加一个 bean 定义注释,例如@ApplicationScoped 用于每个命令,以便它们可以被解析。

关于java - 如何以编程方式查找和注入(inject)限定符包含类名的 CDI 托管 bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29527308/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com