Berbagi teknologi

@RequiredArgsConstructor mengimplementasikan injeksi konstruktor

2024-07-12

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

@RequiredArgsConstructor mengimplementasikan injeksi konstruktor

1. @Autowired Dan@Resource anotasi

@Autowired
  • @Autowired Ini adalah anotasi yang disediakan oleh kerangka Spring dan digunakan untuk merakit dependensi secara otomatis.
  • Dapat digunakan pada bidang, konstruktor, dan metode penyetel.
@Autowired
private ISysUserService userService;
  • 1
  • 2
@Resource
  • @Resource Ini adalah anotasi yang disediakan oleh Java EE, dan Spring juga mendukungnya untuk perakitan dependensi secara otomatis.
  • Umumnya digunakan untuk bidang dan metode penyetel.
@Resource
private ISysUserService userService;
  • 1
  • 2

2. Injeksi konstruktor

Menggunakan Lombok @RequiredArgsConstructor

Konsep dan penggunaan springboot @RequiredArgsConstructor-Tencent Cloud Developer Community-Tencent Cloud (tencent.com)

  • @RequiredArgsConstructor adalah anotasi yang disediakan oleh Lombok, yang secara otomatis akan menghasilkan semuafinal Konstruktor lapangan.
  • Menggunakan injeksi konstruktor memastikan bahwa injeksi ketergantungan selesai ketika objek dibuat, memastikan bahwa semua ketergantungan bukan nol.
@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. Perbandingan dan Keunggulan

injeksi lapangan (@Autowired Dan@Resource
  • keuntungan: Kodenya ringkas dan diberi anotasi langsung di kolom.
  • kekurangan
    • Sulit untuk menguji unit karena objek tiruan perlu disuntikkan melalui refleksi atau cara lain.
    • Injeksi ketergantungan terjadi setelah objek dibuat, yang dapat menyebabkan dependensi tidak diinisialisasi secara lengkap.
    • Melanggar prinsip inversi ketergantungan, kelas secara langsung bergantung pada wadah.
injeksi konstruktor
  • keuntungan
    • Paksa dependensi untuk diinisialisasi sepenuhnya saat objek dibuat, pastikan semua dependensi bukan nol.
    • Lebih mudah untuk menguji unit karena objek tiruan dapat dimasukkan melalui konstruktor.
    • Ini lebih sejalan dengan prinsip inversi ketergantungan dan membuat kelas lebih independen terhadap container.
    • Peningkatan keterbacaan dan pemeliharaan kode, terutama ketika terdapat banyak ketergantungan.
  • kekurangan: Memerlukan kode konstruktor tambahan, tetapi menggunakan kode Lombok @RequiredArgsConstructor Beban ini bisa diringankan.

4. Contoh perbandingan

menggunakan @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
Menggunakan injeksi konstruktor
@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

Melalui metode injeksi konstruktor ini, tidak hanya ketahanan dan pemeliharaan kode yang dapat ditingkatkan, tetapi juga fitur injeksi ketergantungan Spring dan keunggulan kode Lombok yang disederhanakan dapat dimanfaatkan dengan lebih baik.

keuntungan

Blog Injeksi Konstruktor Spring_spring Injeksi Konstruktor-CSDN
Silakan tambahkan deskripsi gambar

5. Tentang anotasi

Saat menggunakan injeksi konstruktor, tidak perlu menambahkan anotasi tambahan, Anda hanya perlu menyediakan konstruktornya. Spring akan secara otomatis mendeteksi konstruktor Anda dan melakukan injeksi ketergantungan.

Gunakan injeksi konstruktor, tidak diperlukan anotasi tambahan
@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
Poin-poin penting dalam menggunakan injeksi konstruktor
  1. Tentukan konstruktor:
    • Tentukan konstruktor di kelas yang berisi semua dependensi yang diperlukan.
  2. Injeksi otomatis pegas:
    • Saat Spring membuat instance Bean, Spring secara otomatis mengenali dan memanggil konstruktor dan memasukkan dependensi yang diperlukan.

Kode sampel

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

Dalam contoh ini, tidak perlu menggunakan anotasi tambahan apa pun untuk memberi anotasi pada konstruktor, Spring akan secara otomatis mengidentifikasi dan memasukkan ketergantungan. (Tentu saja, tidak ada kesalahan yang akan dilaporkan jika ditandai, tetapi hanya @Autowired yang dapat digunakan, dan @Resouce tidak dapat digunakan.@Resource Anotasi biasanya digunakan untuk injeksi metode bidang atau penyetel)

keadaan tambahan
  1. Beberapa konstruktor:
    • Jika ada beberapa konstruktor dalam satu kelas dan hanya satu yang memiliki parameter injeksi, Spring akan menggunakan konstruktor ini untuk injeksi.
    • Jika ada beberapa konstruktor dengan parameter yang dimasukkan, Anda perlu menggunakannya @Autowired anotasi untuk secara eksplisit menentukan konstruktor mana yang akan digunakan.

Kode contoh (beberapa konstruktor)

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

Dalam contoh ini, karena ada banyak konstruktor, Anda perlu menggunakannya @Autowired Anotasi untuk secara eksplisit menentukan konstruktor mana yang digunakan Spring untuk injeksi ketergantungan.