Java Spring自动装配bean导致空指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25991191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 01:38:23  来源:igfitidea点击:

Spring autowired bean causes null pointer

javaspringjunitautowiredspring-annotations

提问by robinjohnobrien

I have a logger class that makes use of a service. Each time a new logger is created, I expect to have access to the singleton scoped logging service.

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

I autowire the logging service into the logger however, a null pointer exception is returned. I have tried a few solutions:

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

  1. manually defining the bean in the application context,
  2. Trying to get the logger to be spring managed but that just resulted in more issues.
  1. 在应用程序上下文中手动定义 bean,
  2. 试图让记录器由 spring 管理,但这只会导致更多问题。

I am trying to get this to work in my junit tests, and I do specify the context file to make use of a different application context. However even if kept identical it does not resolve the issue.

我试图让它在我的 junit 测试中工作,并且我确实指定了上下文文件以使用不同的应用程序上下文。但是,即使保持相同,也不能解决问题。

Please find code below:

请在下面找到代码:

The following is an excerpt from the application context.

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

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

The following is the Logger class.

下面是 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
  }

}

}

I then make use of the Logger in another service in order to log whats going on. (The reason I am writing another logger is to make use of an RabbitMQ server) In the service I instantiate a new instance of the Logger and then use it accordingly.

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

@Service
public class AsyncAccountServiceImplementation implements AsyncAccountService
{
  private static final String GATEWAY_IP_BLOCK = "1";

  private static OurLogger logger = new      OurLogger(AsyncAccountServiceImplementation.class);

...
}

The null pointer occurs in the OurLoggerwhen I try to call any method on the asyncLoggingService.

空指针出现在OurLogger我尝试调用asyncLoggingService.

I then am trying to test the AsyncAccountServiceusing JUnit. I make sure I add the different application context but it still seems to result in the null pointer exception.

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

If you need further information please let me know. I have seen ways to fix this but they don't seem to work so perhaps I have made a mistake somewhere or I am not understanding this all quite correctly.

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

采纳答案by Xstian

When you create an object by new, autowire\inject don't work...

当您通过 new 创建对象时,autowire\inject 不起作用...

See this linkand this linkfor some workaround.

有关一些解决方法,请参阅此链接和此链接

Anyway if you would inject a logger i suggest you thismy answer to another topic.

无论如何,如果你要注入一个记录器,我建议你这是我对另一个主题的回答。

回答by micha

If you are using AspectJ you can use @Configurable:

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

@Configurable
public class OurLogger {
  ..
}

See: Using AspectJ to dependency inject domain objects with Spring

请参阅:使用 AspectJ 使用 Spring 依赖注入域对象

回答by Abderrazak BOUADMA

Within your application context you have to do reference your Logger :

在您的应用程序上下文中,您必须引用您的 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"/>

Then you've to inject it into your service :

然后你必须将它注入你的服务:

@Service
public class AsyncAccountServiceImplementation implements AsyncAccountService
{

 private static final String GATEWAY_IP_BLOCK = "1";

 @Autowired
 private OurLogger logger;

}

回答by Hakim Saifee

Use spring framework Unit test instead of JUnit test to inject your spring bean.

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

May be that will help you.

可能这会帮助你。

回答by smwikipedia

Just want to add my 2 cents.

只想加上我的 2 美分。

I once encountered the same issue when I was not quite used to the life in the IoC world. The @Autowiredfield of one of my beans is null at runtime.

我曾经在不太习惯的时候遇到过同样的问题the life in the IoC world@Autowired我的一个 bean的字段在运行时为空。

The root cause is, instead of using the auto-created bean maintained by the Spring IoC container (whose @Autowiredfield is indeedproperly injected), I am newingmy own instance of that bean and using it. Of course this one's @Autowiredfield is null because Spring has no chance to inject it.

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