web-dev-qa-db-ja.com

Spring autowired Beanによりnullポインターが発生する

サービスを利用するロガークラスがあります。新しいロガーが作成されるたびに、シングルトンスコープのロギングサービスにアクセスできると期待しています。

ロギングサービスをロガーに自動配線していますが、nullポインタ例外が返されます。私はいくつかの解決策を試しました:

  1. アプリケーションコンテキストでBeanを手動で定義する、
  2. ロガーを春の管理になるようにしようとしていますが、それだけでさらに問題が発生しました。

私はこれを私の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
  }

}

次に、別のサービスでロガーを利用して、何が起こっているのかをログに記録します。 (別のロガーを作成している理由は、RabbitMQサーバーを利用するためです)サービスでは、ロガーの新しいインスタンスをインスタンス化し、それに応じて使用します。

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

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

...
}

OurLoggerでメソッドを呼び出そうとすると、asyncLoggingServiceでnullポインターが発生します。

次に、JUnitを使用してAsyncAccountServiceをテストしようとしています。別のアプリケーションコンテキストを確実に追加しますが、それでもnullポインター例外が発生するようです。

さらに情報が必要な場合はお知らせください。私はこれを修正する方法を見てきましたが、それらは機能していないようですので、おそらくどこかで間違いを犯したか、これをすべて正しく理解していない可能性があります。

7
robinjohnobrien

新規でオブジェクトを作成すると、autowire\injectが機能しません...

いくつかの回避策については、この link およびこの link を参照してください。

とにかく、あなたがロガーを注入するなら、私はあなたに提案します this 別のトピックへの私の答え。

8
Xstian

ちょうど私の2セントを追加したいです。

the life in the IoC worldに慣れていないときに同じ問題が発生しました。いずれかのBeanの@Autowiredフィールドが実行時にnullになります。

根本的な原因は、Spring IoCコンテナ(@Autowiredフィールドがindeedが適切に挿入されている)によって維持される自動作成Beanを使用する代わりに、私がnewingその豆とそれを使用しています。もちろん、このフィールドの@Autowiredフィールドはnullです。これは、Springが挿入する機会がないためです。

4
smwikipedia

AspectJを使用している場合は、@Configurable

@Configurable
public class OurLogger {
  ..
}

参照: AspectJを使用して、Springでドメインオブジェクトを依存関係注入する

2
micha

アプリケーションコンテキスト内で、ロガーを参照する必要があります。

<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;

}
1

Spring Beanを注入するには、JUnitテストではなくSpringフレームワークのユニットテストを使用します。

それはあなたを助けるかもしれません。

1
Hakim Saifee