我有以下类(这是一个JPA实体监听器):
@Service
public class AuditLogListener {
@Autowired
IDomainObjectDAO domainObjectDAO;
@PostLoad
public void saveOldData(DomainObject obj) {
domainObjectDAO.findAll();
System.out.println("after Load");
}
@PreUpdate
public void logChanges(DomainObject obj) {
}
}
归档domainObjectDAO
被Spring识别,并根据日志自动连接。
摘自日志:
[http-8080-1] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Found injected element on class [com.legolas.entityListeners.AuditLogListener]: AutowiredFieldElement for com.legolas.dao.interfaces.IDomainObjectDAO com.legolas.entityListeners.AuditLogListener.domainObjectDAO
[http-8080-1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'auditLogListener' to allow for resolving potential circular references
[http-8080-1] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'auditLogListener': AutowiredFieldElement for com.legolas.dao.interfaces.IDomainObjectDAO com.legolas.entityListeners.AuditLogListener.domainObjectDAO
[http-8080-1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'domainObjectDAO'
[http-8080-1] DEBUG org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - Autowiring by type from bean name 'auditLogListener' to bean named 'domainObjectDAO'
但是在调试模式下检查字段时,我看到字段为空,并且在调用findAll()
方法时抛出异常。
为什么该字段为null并且有办法解决这个问题?
谢谢。
答案 0 :(得分:5)
JPA监听器由JPA提供程序而不是Spring实例化,因此它们的依赖关系不是由Spring注入的。也就是说,现在你有两个类的实例 - 一个由JPA使用(没有注入依赖项),另一个由Spring实例化(你在日志中看到它)。
因此,您需要将依赖项注入到不由Spring管理的对象中。您有两种选择:
使用某种静态或线程绑定状态从侦听器获取对ApplicationContext
的引用。例如,在典型的Spring Web应用程序中,您可以按如下方式获取它:
RequestContextUtils.getWebApplicationContext(
(SerlvetRequest) RequestContextHolder.currentRequestAttributes()
.resolveReference(RequestAttributes.REFERENCE_REQUEST))