gpt4 book ai didi

java - CDI - @Injected 字段为空

转载 作者:行者123 更新时间:2023-12-02 10:08:50 25 4
gpt4 key购买 nike

我想在应用程序启动时初始化一个集合并用数据填充它。然后我想在我的应用程序中的任何地方访问它。例如,我希望我的 REST API 可以访问已填充数据的共享集合。

我首先尝试使用带有 @Startup 和 @Singleton 注释的启动类来完成此操作。当我在那里注入(inject) userService 时,我遇到了一些问题,并且由于这篇文章中的建议:@Inject and @PostConstruct not working in singleton pattern我尝试使用 @ApplicationScoped 注释来做到这一点:

@Named
@ApplicationScoped
public class KwetterApp {

@Inject
private UserService service;

@PostConstruct
public void init() {
try {
User harry = new User("Harry", "harry@outlook.com", "New York", "http://harry.com", "Hi, I'm Harry!", UserType.REGULAR);
User nick = new User("Nick", "nick@outlook.com", "California", "http://nick.com", "Hi, I'm Nick!", UserType.REGULAR);
User jane = new User("Jane", "jane@outlook.com", "Texas", "http://jane.com", "Hi, I'm Jane!", UserType.REGULAR);

Tweet tweet = new Tweet("eating...", harry);
Tweet tweet1 = new Tweet("swimming...", harry);
Tweet tweet2 = new Tweet("jogging...", jane);

harry.addTweet(tweet);
harry.addTweet(tweet1);
jane.addTweet(tweet2);
service.create(harry);
service.create(nick);
service.create(jane);
}
catch (Exception e){
e.printStackTrace();
}
}

public UserService getService() {
return service;
}
}

我将此类注入(inject)到我的休息服务中:

@RequestScoped
@Path("/user")
public class UserRest {

// @Inject
// private UserService userService;

@Inject
private KwetterApp kwetterApp;

// private KwetterApp kwetterApp = KwetterApp.getInstance();
private UserService userService = kwetterApp.getService();

@GET
@Produces({"application/json"})
public List<User> get() throws UserException {

return userService.getAll();
}
}

注入(inject)此 KwetterApp 时会导致以下异常:

StandardWrapperValve[rest.RestApplication]: Servlet.service() for servlet rest.RestApplication threw exception
java.lang.NullPointerException
at rest.UserRest.<init>(UserRest.java:27)
at rest.UserRest$Proxy$_$$_WeldClientProxy.<init>(Unknown Source)

我有一个空的 beans.xml 文件,其 bean-discovery-mode 设置为“all”。 CDI 框架应该识别我的 KwetterApp 类进行注入(inject),对吧?为什么为空?

提前致谢,

迈克

最佳答案

这里

@Inject
private KwetterApp kwetterApp;
private UserService userService = kwetterApp.getService();

我认为 kwetterApp 字段不会在 userService 之前设置。
CDI 将在构造对象后设置该字段。

无论如何都应该使用的替代方案是构造函数注入(inject)

@RequestScoped
@Path("/user")
public class UserRest {
private KwetterApp kwetterApp;
private UserService userService;

protected UserRest() {}

@Inject
public UserRest(final KwetterApp kwetterApp) {
this.kwetterApp = kwetterApp;
this.userService = kwetterApp.getService();
}

@GET
@Produces({"application/json"})
@Override
public List<User> get() throws UserException {
return userService.getAll();
}
}

需要一个protected构造函数,因为@RequestScoped是一个普通范围的bean,并且它必须是可代理的,如规范中所述。

唯一不需要空构造函数的注释是@Singleton(来自javax.inject)。

关于java - CDI - @Injected 字段为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55144544/

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