Spring @Resource 注入 returns 一个 NullPointerException

Spring @Resource injection returns a NullPointerException

我正在尝试使用 entityInterceptor 来记录某些对象的更改以用于审计跟踪。

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>   
        <property name="entityInterceptor">    
            <bean class="x.y.z.PropertyChangeInterceptor"/>  
        </property>         
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                ------ ------
            </props>
        </property>
        <property name="packagesToScan">
            <array>
                <value>x.y.z</value>
            </array>
        </property>
    </bean>

我为要监视的对象自定义更改侦听器到 PropertyChangeInterceptor 构造函数,它具有 onFlushDirty、onSave 和 postFlush 的覆盖方法。

 public PropertyChangeInterceptor() {
   listeners = new HashMap<>();
       listeners.put(Customer.class, new CustomerChangeListener());
   }

现在问题出现在我的 CustomerChangeListener class 中。我正在注入一个服务,我打算用它来将审计日志保存到我的数据库中。当我尝试使用该服务时,该服务抛出空指针异常。有趣的是,除了这个 class,这项服务在我的所有其他控制器上运行良好。 class 实现 PropertyChangeListener。

@Component
public class CustomerChangeListener implements PropertyChangeListener<Customer> {

    Logger log = LoggerFactory.getLogger(CustomerChangeListener.this.getClass());

    @Resource(name = "audittrailService")
    private ServiceInterface audittrailService;
       ......
       ......
 @Override
    public void logIt(String action, Object entity) {
        try {
            audittrailService.findById(1); **<==Error Occurs here**
            ..........
            audittrailService.save(trail);
        } catch (UnknownHostException uhe) {
            log.error("Error Saving audit trail -UnknownHostException", uhe);
        } catch (Exception e) {
            log.error("Error Saving audit trail", e);
        }
    }

我相信我的 Spring 注释配置没问题,因为它们适用于其他 classes。

<!-- Enable Spring Annotation Configuration -->
    <context:annotation-config/>

    <aop:aspectj-autoproxy proxy-target-class="true" />

    <!-- Necessary to get the entity manager injected into the factory bean -->
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 

    <!--Enable Spring's Exception Translation Mechanism-->
   <!-- Enable Spring Annotation Configuration -->
    <context:annotation-config/>

    <aop:aspectj-autoproxy proxy-target-class="true" />

    <!-- Necessary to get the entity manager injected into the factory bean -->
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 

    <!--Enable Spring's Exception Translation Mechanism-->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

    <context:component-scan base-package="com.anchor.anchorfused4.Service"/>
    <context:component-scan base-package="..."/>
    <context:component-scan base-package="..."/>
    <context:component-scan base-package="com.anchor.anchorfused4.Listeners"/>

这是错误日志。

Severe:   java.lang.NullPointerException
at com.anchor.anchorfused4.Listeners.CustomerChangeListener.logIt(CustomerChangeListener.java:59)
at com.anchor.anchorfused4.Listeners.PropertyChangeInterceptor.postFlush(PropertyChangeInterceptor.java:107)
at org.hibernate.event.internal.AbstractFlushingEventListener.postFlush(AbstractFlushingEventListener.java:388)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:53)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:558)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:496)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.anchor.anchorfused4.Service.Impl.CustomerService$$EnhancerBySpringCGLIB$bf59009.update(<generated>)
at com.anchor.anchorfused4.Controller.CustomerController.updateCustomer(CustomerController.java:280)

@dit 要求的启动日志

Info:   GlassFish Server Open Source Edition  4.1  (13) startup time : Felix (6,084ms), startup services(1,620ms), total(7,704ms)
Info:   Grizzly Framework 2.3.15 started in: 2ms - bound to [/0.0.0.0:7676]
Info:   HV000001: Hibernate Validator 5.0.0.Final
Info:   JMXStartupService has started JMXConnector on JMXService URL service:jmx:rmi://user-PC:8686/jndi/rmi://user-PC:8686/jmxrmi
Info:   Registered com.sun.enterprise.glassfish.bootstrap.osgi.EmbeddedOSGiGlassFishImpl@55b89494 as OSGi service registration: org.apache.felix.framework.ServiceRegistrationImpl@6e889444.
Info:   Grizzly Framework 2.3.15 started in: 8ms - bound to [/0.0.0.0:8080]
Info:   Grizzly Framework 2.3.15 started in: 15ms - bound to [/0.0.0.0:8181]
Info:   visiting unvisited references
Info:   Java security manager is disabled.
Info:   Entering Security Startup Service.
Info:   Loading policy provider com.sun.enterprise.security.provider.PolicyWrapper.
Info:   Security Service(s) started successfully.
Info:   Created HTTP listener http-listener-1 on host/port 0.0.0.0:8080
Info:   Created HTTP listener http-listener-2 on host/port 0.0.0.0:8181
Info:   Created HTTP listener admin-listener on host/port 0.0.0.0:4848
Info:   Created virtual server server
Info:   Created virtual server __asadmin
Info:   Setting JAAS app name glassfish-web
Info:   Virtual server server loaded default web module 
Info:   Initializing Mojarra 2.2.7 ( 20140610-1547 https://svn.java.net/svn/mojarra~svn/tags/2.2.7@13362) for context '/MinjaAnchorERP'
Info:   SecretKey: J8WnmCmANrta3jQL3rPITA==
Info:   Running on PrimeFaces 5.3
Info:   Running on PrimeFaces Extensions 4.0.0
Info:   WebModule[null] ServletContext.log():Initializing Spring root WebApplicationContext
Severe:   [admin-listener(5)] INFO org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
Severe:   [admin-listener(5)] INFO org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Mon Sep 05 12:37:49 EAT 2016]; root of context hierarchy
Severe:   [admin-listener(5)] INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/config/web-application-config.xml]
Severe:   [admin-listener(5)] INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/config/data-access-config.xml]
Severe:   [admin-listener(5)] INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/config/webflow-config.xml]
Severe:   [admin-listener(5)] INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/config/webmvc-config.xml]
Severe:   [admin-listener(5)] INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/config/security-config.xml]
Severe:   [admin-listener(5)] INFO org.springframework.security.core.SpringSecurityCoreVersion - You are running with Spring Security Core 3.2.5.RELEASE
Severe:   [admin-listener(5)] INFO org.springframework.security.config.SecurityNamespaceHandler - Spring Security 'config' module version is 3.2.5.RELEASE
.......
.......
Severe:   [admin-listener(5)] INFO com.anchor.anchorfused4.Listeners.PropertyChangeInterceptor - Init
Info:   HCANN000001: Hibernate Commons Annotations {4.0.2.Final}
Info:   HHH000412: Hibernate Core {4.2.4.Final}
Info:   headless=true
Severe:   [admin-listener(5)] INFO com.anchor.anchorfused4.Listeners.CustomerChangeListener - init CustomerChangeListener
Severe:   [admin-listener(5)] INFO com.anchor.anchorfused4.Listeners.PropertyChangeInterceptor - Init
Severe:   [admin-listener(5)] INFO com.anchor.anchorfused4.Controller.PermissionMapController - Init
Severe:   [admin-listener(5)] INFO org.springframework.cache.ehcache.EhCacheManagerFactoryBean - Initializing EhCache CacheManager

我设法解决了这个问题。

我意识到我需要自动装配自定义 class CustomerChangeListener 而不是使用 new CustomerChangeListener() 创建它,但是自动装配此 class 拒绝工作。该项目甚至无法启动,不像之前在保存时抛出异常。

基于这个新错误的一点研究,我发现通过 spring 注释注入 classes 上的空指针的原因是因为 entityInterceptor 是休眠管理的并且未 spring 管理。

这里的回答帮了大忙。

除了创建 DelegateInterceptor 之外,我还必须将侦听器从 PropertyChangeInterceptor 构造函数移至其 @PostConstruct

public PropertyChangeInterceptor() {
   //listeners = new HashMap<>(); 
   //listeners.put(Customer.class, new CustomerChangeListener());
}

@PostConstruct
public void init() {
    StaticDelegateInterceptor.setInterceptor(this);
    listeners = new HashMap<>(); //move to here
    listeners.put(Customer.class, customerChangeListener);
}