自动装配字段仍为空

时间:2010-11-14 16:53:10

标签: java spring jpa

我有以下类(这是一个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并且有办法解决这个问题?

谢谢。

1 个答案:

答案 0 :(得分:5)

JPA监听器由JPA提供程序而不是Spring实例化,因此它们的依赖关系不是由Spring注入的。也就是说,现在你有两个类的实例 - 一个由JPA使用(没有注入依赖项),另一个由Spring实例化(你在日志中看到它)。

因此,您需要将依赖项注入到不由Spring管理的对象中。您有两种选择:

  • 使用@Configurable

  • 使用某种静态或线程绑定状态从侦听器获取对ApplicationContext的引用。例如,在典型的Spring Web应用程序中,您可以按如下方式获取它:

    RequestContextUtils.getWebApplicationContext(
        (SerlvetRequest) RequestContextHolder.currentRequestAttributes()
            .resolveReference(RequestAttributes.REFERENCE_REQUEST))