Обмен технологиями

@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 Полевой конструктор.
  • Использование внедрения конструктора гарантирует, что внедрение зависимостей будет завершено при создании объекта, гарантируя, что все зависимости не равны нулю.
@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
  • преимущество: Код краток и аннотирован непосредственно в полях.
  • недостаток
    • Сложно провести модульное тестирование, поскольку фиктивные объекты необходимо внедрять посредством отражения или другими способами.
    • Внедрение зависимостей происходит после создания объекта, что может привести к неполной инициализации зависимостей.
    • Нарушая принцип инверсии зависимостей, класс напрямую зависит от контейнера.
внедрение конструктора
  • преимущество
    • Принудительно инициализировать зависимости при создании объекта, гарантируя, что все зависимости не равны нулю.
    • Легче модульное тестирование, поскольку макеты объектов можно внедрить через конструктор.
    • Это больше соответствует принципу инверсии зависимостей и делает класс более независимым от контейнера.
    • Улучшена читаемость и удобство обслуживания кода, особенно при наличии большого количества зависимостей.
  • недостаток: Требуется дополнительный код конструктора, но используется 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's Constructor Injection_spring Constructor Injection-Блог 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. Несколько конструкторов:
    • Если в классе несколько конструкторов и только один из них имеет параметры внедрения, 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 использует для внедрения зависимостей.