技術共有

@RequiredArgsConstructor はコンストラクター インジェクションを実装します

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

@RequiredArgsConstructor はコンストラクター インジェクションを実装します

1. @Autowired そして@Resource 注釈

@Autowired
  • @Autowired これは Spring フレームワークによって提供されるアノテーションであり、依存関係を自動的にアセンブルするために使用されます。
  • フィールド、コンストラクター、セッター メソッドで使用できます。
@Autowired
private ISysUserService userService;
  • 1
  • 2
@Resource
  • @Resource これは Java EE によって提供されるアノテーションであり、Spring も依存関係の自動アセンブリのためにこれをサポートしています。
  • 通常、フィールドとセッター メソッドに使用されます。
@Resource
private ISysUserService userService;
  • 1
  • 2

2. コンストラクターの注入

ロンボク島を利用する @RequiredArgsConstructor

springboot @RequiredArgsConstructor の概念と使用法 - Tencent Cloud Developer Community - Tencent Cloud (tencent.com)

  • @RequiredArgsConstructor Lombok によって提供されるアノテーションであり、すべてのアノテーションが自動的に生成されます。final フィールドコンストラクター。
  • コンストラクター注入を使用すると、オブジェクトの作成時に依存関係の注入が完了し、すべての依存関係が null でないことが保証されます。
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController {
    private final ISysUserService userService;
    private final ISysRoleService roleService;
    private final ISysPostService postService;
    private final ISysDeptService deptService;
    private final ISysUserPostService userPostService;
    
    // 构造函数由 Lombok 自动生成,注入所有 final 字段
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3. 比較と利点

フィールド注入 (@Autowired そして@Resource
  • アドバンテージ: コードは簡潔で、フィールドに直接注釈が付けられています。
  • 欠点がある
    • リフレクションなどの手段を介してモックオブジェクトを挿入する必要があるため、単体テストが困難です。
    • 依存関係の注入はオブジェクトの作成後に発生するため、依存関係が不完全に初期化される可能性があります。
    • 依存関係逆転の原則に違反すると、クラスはコンテナに直接依存します。
コンストラクターインジェクション
  • アドバンテージ
    • オブジェクトの作成時に依存関係が完全に初期化されるように強制し、すべての依存関係が null でないことを確認します。
    • コンストラクターを通じてモック オブジェクトを挿入できるため、単体テストが容易になります。
    • これは依存関係逆転の原則に沿っており、クラスをコンテナからより独立させます。
    • 特に依存関係が多い場合のコードの可読性と保守性が向上しました。
  • 欠点がある: 追加のコンストラクター コードが必要ですが、Lombok のコードを使用します。 @RequiredArgsConstructor この負担は軽減できます。

4. 比較例

使用 @Autowired
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController {
    
    @Autowired
    private ISysUserService userService;
    
    @Autowired
    private ISysRoleService roleService;
    
    @Autowired
    private ISysPostService postService;
    
    @Autowired
    private ISysDeptService deptService;
    
    @Autowired
    private ISysUserPostService userPostService;

    // 其他代码
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
コンストラクターインジェクションを使用する
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController {
    private final ISysUserService userService;
    private final ISysRoleService roleService;
    private final ISysPostService postService;
    private final ISysDeptService deptService;
    private final ISysUserPostService userPostService;

    // 其他代码
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

このコンストラクターインジェクションの手法により、コードの堅牢性や保守性が向上するだけでなく、Spring の依存性インジェクション機能や Lombok の簡素化されたコードの利点も活用できます。

利点

Spring のコンストラクター インジェクション_spring コンストラクター インジェクション-CSDN ブログ
画像の説明を追加してください

5. アノテーションについて

コンストラクター インジェクションを使用する場合、追加のアノテーションを追加する必要はなく、コンストラクターを提供するだけで済みます。 Spring はコンストラクターを自動的に検出し、依存関係の注入を実行します。

コンストラクターインジェクションを使用します。追加のアノテーションは必要ありません
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController {
    private final ISysUserService userService;
    private final ISysRoleService roleService;
    private final ISysPostService postService;
    private final ISysDeptService deptService;
    private final ISysUserPostService userPostService;

    // 自己编写构造函数
    public SysUserController(ISysUserService userService, 
                             ISysRoleService roleService, 
                             ISysPostService postService, 
                             ISysDeptService deptService, 
                             ISysUserPostService userPostService) {
        this.userService = userService;
        this.roleService = roleService;
        this.postService = postService;
        this.deptService = deptService;
        this.userPostService = userPostService;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
コンストラクターインジェクションを使用する際の重要なポイント
  1. コンストラクターを定義します。
    • 必要な依存関係をすべて含むクラス内にコンストラクターを定義します。
  2. スプリング自動噴射:
    • Spring は Bean インスタンスを作成するときに、コンストラクターを自動的に識別して呼び出し、必要な依存関係を注入します。

サンプルコード

package com.example.demo.controller;

import com.example.demo.service.ISysUserService;
import com.example.demo.service.ISysRoleService;
import com.example.demo.service.ISysPostService;
import com.example.demo.service.ISysDeptService;
import com.example.demo.service.ISysUserPostService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/system/user")
public class SysUserController {

    private final ISysUserService userService;
    private final ISysRoleService roleService;
    private final ISysPostService postService;
    private final ISysDeptService deptService;
    private final ISysUserPostService userPostService;

    // 构造函数注入
    public SysUserController(ISysUserService userService, 
                             ISysRoleService roleService, 
                             ISysPostService postService, 
                             ISysDeptService deptService, 
                             ISysUserPostService userPostService) {
        this.userService = userService;
        this.roleService = roleService;
        this.postService = postService;
        this.deptService = deptService;
        this.userPostService = userPostService;
    }

    // 你的控制器方法
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

この例では、コンストラクターに注釈を付けるために追加の注釈を使用する必要はなく、Spring が自動的に依存関係を識別して注入します。 (もちろんマークしてもエラーは報告されませんが、使用できるのは@Autowiredのみで、@Resouceは使用できません。@Resource アノテーションは通常、フィールドまたはセッター メソッドの注入に使用されます)

追加の状況
  1. 複数のコンストラクター:
    • クラス内に複数のコンストラクターがあり、そのうちの 1 つだけが注入パラメーターを持つ場合、Spring はこのコンストラクターを注入に使用します。
    • 挿入されたパラメーターを持つ複数のコンストラクターがある場合は、次を使用する必要があります。 @Autowired アノテーションを使用して、使用するコンストラクターを明示的に指定します。

サンプルコード (複数のコンストラクター)

package com.example.demo.controller;

import com.example.demo.service.ISysUserService;
import com.example.demo.service.ISysRoleService;
import com.example.demo.service.ISysPostService;
import com.example.demo.service.ISysDeptService;
import com.example.demo.service.ISysUserPostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/system/user")
public class SysUserController {

    private final ISysUserService userService;
    private final ISysRoleService roleService;
    private final ISysPostService postService;
    private final ISysDeptService deptService;
    private final ISysUserPostService userPostService;

    // 使用 @Autowired 明确指定使用哪个构造函数
    @Autowired
    public SysUserController(ISysUserService userService, 
                             ISysRoleService roleService, 
                             ISysPostService postService, 
                             ISysDeptService deptService, 
                             ISysUserPostService userPostService) {
        this.userService = userService;
        this.roleService = roleService;
        this.postService = postService;
        this.deptService = deptService;
        this.userPostService = userPostService;
    }

    // 另一个构造函数
    public SysUserController(ISysUserService userService) {
        this.userService = userService;
        this.roleService = null;
        this.postService = null;
        this.deptService = null;
        this.userPostService = null;
    }

    // 你的控制器方法
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

この例では、複数のコンストラクターがあるため、次を使用する必要があります。 @Autowired Spring が依存関係の注入にどのコンストラクターを使用するかを明示的に指定するためのアノテーション。