Spring autowired bean导致空指针

时间:2014-09-23 09:11:26

标签: java spring junit autowired spring-annotations

我有一个使用服务的记录器类。每次创建新的记录器时,我都希望能够访问单例范围的日志记录服务。

我将日志记录服务自动装入记录器,但是返回空指针异常。我尝试了一些解决方案:

  1. 在应用程序上下文中手动定义bean,
  2. 尝试让记录器进行弹簧管理但这只会导致更多问题。
  3. 我试图在junit测试中使用它,并且我确实指定了上下文文件以使用不同的应用程序上下文。但即使保持相同,也无法解决问题。

    请在下面找到代码:

    以下是应用程序上下文的摘录。

    <context:component-scan base-package="com.platform"/>
    <bean id="asyncLoggingService" class="com.platform.services.AsyncLoggingServiceImplementation" scope="prototype"/>
    

    以下是Logger类。

    package com.platform.utils;
    
    
    import com.platform.services.AsyncLoggingService;
    import org.joda.time.DateTime;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    
    public class OurLogger
    {
    
      private static Logger logger;
    
      @Autowired
      private AsyncLoggingervice asyncLoggingService;
    
      public OurLogger(Class Clazz)
      {
        logger = LoggerFactory.getLogger(Clazz);
      }
    
    
      public void trace(TraceableObject object, String message)
      { 
        //Do nothing yet
      }
    

    }

    然后我在另一个服务中使用Logger来记录最新情况。 (我编写另一个记录器的原因是使用RabbitMQ服务器)在服务中,我实例化Logger的新实例,然后相应地使用它。

    @Service
    public class AsyncAccountServiceImplementation implements AsyncAccountService
    {
      private static final String GATEWAY_IP_BLOCK = "1";
    
      private static OurLogger logger = new      OurLogger(AsyncAccountServiceImplementation.class);
    
    ...
    }
    

    当我尝试调用OurLogger上的任何方法时,空指针出现在asyncLoggingService中。

    然后我尝试使用JUnit测试AsyncAccountService。我确保添加不同的应用程序上下文,但它似乎仍然导致空指针异常。

    如果您需要更多信息,请告诉我。我已经看到了解决这个问题的方法,但它们似乎没有用,所以也许我在某个地方犯了错误,或者我并没有完全理解这一点。

5 个答案:

答案 0 :(得分:8)

当你用new创建一个对象时,autowire \ inject不会工作......

有关解决方法,请参阅此link和此link

无论如何,如果您注射记录器,我建议您this我对另一个主题的回答。

答案 1 :(得分:4)

只想加2美分。

当我不熟悉the life in the IoC world时,我曾遇到过同样的问题。我的一个bean的@Autowired字段在运行时为空。

根本原因是,不是使用由Spring IoC容器维护的自动创建的bean(其@Autowired字段正确注入indeed),而是newing我自己的实例那个bean并使用它。当然这个@Autowired字段是空的,因为Spring没有机会注入它。

答案 2 :(得分:2)

如果您使用的是AspectJ,可以使用@Configurable

@Configurable
public class OurLogger {
  ..
}

请参阅:Using AspectJ to dependency inject domain objects with Spring

答案 3 :(得分:1)

在您的应用程序上下文中,您必须参考您的Logger:

<context:component-scan base-package="com.platform"/>
<bean id="asyncLoggingService" class="com.platform.services.AsyncLoggingServiceImplementation" scope="prototype"/>
<bean id="ourLogger" class="com.platform.utils.OurLogger"/>

然后你要把它注入你的服务:

@Service
public class AsyncAccountServiceImplementation implements AsyncAccountService
{

 private static final String GATEWAY_IP_BLOCK = "1";

 @Autowired
 private OurLogger logger;

}

答案 4 :(得分:1)

使用spring框架单元测试而不是JUnit测试来注入你的spring bean。

可能会对你有帮助。