【发布时间】:2016-02-27 00:22:12
【问题描述】:
第 1 类:Repository.java:
@ApplicationScoped
public class Repository {
@Inject
private EntityManager em;
public Term findById(Long id) {
return em.find(Term.class, id);
}
}
第 2 类:Word.java
@Named
@RequestScoped
public class Word {
@Inject
private Logger log;
@Inject
private Repository repository;
private Term term;
public Word() {
}
public Word(Long id) {
try{
term = this.findTermById(id);
}catch(Exception e) {
e.printStackTrace();
}
}
@Produces
@Named
public Term getTerm() {
return term;
}
public Term findTermById(Long id) {
Term term = repository.findById(id);
if(term==null) {
log.info("Can't find this word from database: " + term);
}
return term;
}
}
第 3 类:Resources.java
public class Resources {
@Produces
@PersistenceContext
private EntityManager em;
@Produces
public Logger produceLog(InjectionPoint injectionPoint) {
return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
}
@Produces
@RequestScoped
public FacesContext produceFacesContext() {
return FacesContext.getCurrentInstance();
}
}
这两个类的问题在于,在运行服务器时,它会在该行抛出 NullPointerException:
Term term = repository.findById(id);
这意味着注入对象“repository”失败,因为调试显示“repository=null”。
@Inject
private Repository repository;
为什么注入不成功?谢谢。
【问题讨论】:
-
如何获得对 Word 实例的引用?异常的堆栈跟踪是什么?
-
问题出在你的
Word构造函数中——你想使用依赖,但是在构造函数中它们还没有被注入。不要在 CDI 中使用构造函数,将所有逻辑从那里移到带有注释@PostConstruct的方法中。如果您遇到任何进一步的问题,还要用@Dependent注释您的Resource类(如果一个类具有采用InjectionPoint参数的@Produces方法,它必须 是依赖范围)。 -
@Geinmachi,问题是如何将参数“Id”传递给 Word 对象,以便创建它?我可以将构造函数移动到 PostConstruct 方法,但是什么时候调用这个方法进行初始化?
-
这是另一个问题。您不应该通过
new创建托管 bean。如果你这样做(我猜你是通过使用带参数的构造函数来做到的),那么它不会由容器管理,并且不会注入任何东西(生命周期也失败)。你应该说明你在哪里使用这个构造函数,也许可以考虑使用@Produces方法。 -
我明白了。谢谢你。我会改变设计。
标签: hibernate jpa dependency-injection jboss cdi