1. 概要

このチュートリアルでは、AutowiredフィールドでNullPointerExceptionを引き起こす一般的なエラーを確認します。 また、問題を解決する方法についても説明します。

2. 問題の提示

まず、空のdoWorkメソッドを使用してSpringコンポーネントを定義しましょう。

@Component
public class MyComponent {
    public void doWork() {}
}

次に、サービスクラスを定義しましょう。 Spring容量を使用して、サービス内に MyComponent beanを挿入し、サービスメソッド内でdoWorkメソッドを呼び出すことができるようにします。

public class MyService {
    
    @Autowired
    MyComponent myComponent;
    
    public String serve() {
        myComponent.doWork();
        return "success";
    }
}

次に、サービスをインスタンス化してserveメソッドを呼び出すコントローラーを追加しましょう。

@Controller
public class MyController {
    
    public String control() {
        MyService userService = new MyService();
        return userService.serve();
    }
}

一見すると、コードは完全に正常に見えるかもしれません。 ただし、アプリケーションを実行した後、コントローラーの制御メソッドを呼び出すと、次の例外が発生します。

java.lang.NullPointerException: null
  at com.baeldung.autowiring.service.MyService.serve(MyService.java:14)
  at com.baeldung.autowiring.controller.MyController.control(MyController.java:12)

ここで何が起こったのですか? コントローラでMyServiceコンストラクタを呼び出すと、Springによって管理されないオブジェクトが作成されました。 このMyServiceオブジェクトの存在の手がかりがないため、Springはその中にMyComponentBeanを挿入できません。 したがって、 MyComponent 作成したMyServiceオブジェクト内のインスタンスはnullのままになり、 NullPointerException このオブジェクトのメソッドを呼び出そうとすると取得します。

3. 解決

この問題を解決するには、コントローラーで使用されるMyServiceインスタンスをSpring管理のBeanにする必要があります。

まず、SpringにMyServiceクラスのBeanを生成するように指示しましょう。 これを実現するためのさまざまな可能性があります。 最も簡単な方法は、MyServiceクラスを@Componentアノテーションまたはその派生物で装飾することです。 たとえば、次のようにすることができます。

@Service
public class MyService {
    
    @Autowired
    MyComponent myComponent;
    
    public String serve() {
        myComponent.doWork();
        return "success";
    }
}

同じ目標を達成するためのもう1つの方法は、[X52X]@Beanメソッドを@Configurationファイルに追加することです。

@Configuration
public class MyServiceConfiguration {

    @Bean
    MyService myService() {
        return new MyService();
    }
}

ただし、MyServiceクラスをSpring管理のBeanに変換するだけでは不十分です。 ここで、 new を呼び出すのではなく、コントローラー内で自動配線する必要があります。 コントローラの固定バージョンがどのように見えるかを見てみましょう。

@Controller
public class MyController {
    
    @Autowired
    MyService myService;
    
    public String control() {
        return myService.serve();
    }
}

これで、制御メソッドを呼び出すと、serveメソッドの結果が期待どおりに返されます。

4. 結論

この記事では、Springインジェクションを、コンストラクターを呼び出して作成したオブジェクトと意図せずに混合すると、NullPointerExceptionが発生する非常に一般的なエラーが発生しました。 この責任を回避することで問題を修正し、mic-macを使用して、自分で管理していたオブジェクトをSpring管理のBeanに変換しました。

いつものように、コードはGitHubから入手できます。