Java CDI-@注入字段为空

Java CDI-@注入字段为空,java,cdi,Java,Cdi,我想初始化一个集合,并在应用程序启动时用数据填充它。然后我想在我的应用程序中的任何地方访问它。例如,我希望我的RESTAPI可以访问已经填充了数据的共享集合 我首先尝试使用一个带有@startup和@Singleton注释的startup类来实现它。当我将我的userService注入其中时,我遇到了一些问题,并且由于这篇文章中的建议:我尝试使用@ApplicationScoped注释来实现这一点: @Named @ApplicationScoped public class KwetterAp

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

我首先尝试使用一个带有@startup和@Singleton注释的startup类来实现它。当我将我的userService注入其中时,我遇到了一些问题,并且由于这篇文章中的建议:我尝试使用@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;
    }
}
我将该类注入我的rest服务:

@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();
    }
}
@RequestScoped
@路径(“/user”)
公共类用户REST{
//@注入
//私人用户服务;
@注入
私人KwetterApp KwetterApp;
//private KwetterApp KwetterApp=KwetterApp.getInstance();
private UserService UserService=kwetterApp.getService();
@得到
@产生({“应用程序/json”})
public List get()引发UserException{
返回userService.getAll();
}
}
注入此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)
StandardWrapperValve[rest.RestApplication]:Servlet rest.RestApplication的Servlet.service()引发异常
java.lang.NullPointerException
UserRest.(UserRest.java:27)
处于静止状态。UserRest$Proxy$\u$\ uWeldClientProxy。(未知源)
我有一个bean发现模式设置为“all”的空beans.xml文件。CDI框架应该识别我的KwetterApp类以进行注入,对吗?为什么它是空的

提前感谢,

迈克

在这里

@Inject
private KwetterApp kwetterApp;
private UserService userService = kwetterApp.getService();
我认为
kwetterApp
字段不会在
userService
之前设置
CDI
将在构建对象后设置该字段

无论如何都应该使用的另一种方法是构造函数注入

@RequestScoped
@路径(“/user”)
公共类用户REST{
私人KwetterApp KwetterApp;
私人用户服务;
受保护的UserRest(){}
@注入
公共用户REST(最终KWETTERAP KWETTERAP){
this.kwetterApp=kwetterApp;
this.userService=kwetterApp.getService();
}
@得到
@产生({“应用程序/json”})
@凌驾
public List get()引发UserException{
返回userService.getAll();
}
}
由于
@RequestScoped
是一个普通作用域bean,并且它必须是可代理的,因此需要
受保护的
构造函数,如规范中所述


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

如果要使用注入bean初始化对象,则必须使用@PostConstruct注释方法,因为注入的CDIBean仅在CDI中@postcontract注释的方法和之后可用,而在字段初始化或构造函数调用期间不可用


因此,UserService已经是一个cdibean了,您可以将它注入到您的rest服务bean中,因为它将是当前活动范围内使用的同一个bean。KwetterApp在当前活动范围内可用,因此UserService也将可用。只有@Dependend作用域bean的行为不同,因此每个bean都提供了自己的实例。

感谢您的反应。当我这样做时,我得到一个“普通作用域bean类rest.UserRest不可代理,因为它没有参数构造函数”错误。但是,创建一个空的无参数构造函数会导致stackoverflow错误。@Maikkey,我会选择接口路由。这是因为代理是如何创建的。(在Spring中,由于CGLIB版本的原因,不需要使用无参数构造函数)如果需要示例,请告诉我。示例永远不会有坏处:)。但是我不明白为什么它会使用接口而不是实际的类本身?@Maikkey我认为这是因为CDI实现实现了接口而不是扩展了类。扩展类意味着必须调用超级构造函数(在本例中,使用参数,因此CDI不知道该做什么)
@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();
  }
}