第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;
为什么注射不成功?谢谢。
答案 0 :(得分:1)
正如@Geinmachi所说,你在构造函数中调用它,但是你没有在构造函数中注入它,而是在字段级别上,直到@PostConstruct才初始化它。
您可以使用构造函数注入将存储库作为参数注入,但您不应该手动实例化Word,而是通过CDI注入。
@Inject
public Word(Repository repo) {
this.repo = repo;
}
一般情况下,构造函数永远不应该执行操作(比如你正在进行的数据库查找),这是非常糟糕的做法,因为没有人知道来自外部的行为加上你在@Inject期间不会有事务。此外,您不应手动实例化CDI bean,因为它们的生命周期由CDI管理,并且旨在通过@Inject使用。
此外,通过使用Applicationscoped实体管理器,您将遇到并发问题,它应该是请求编写的。
答案 1 :(得分:0)
你没有完整的堆栈跟踪吗?我认为NullPointerException可能来自您的Repository bean中的5*cos(4x+2)
为空。
CDI没有看到你的类资源,因为它没有定义bean。 (据我所知,从代码中可以看出。)