@RequiredArgsConstructor实现构造器注入

@RequiredArgsConstructor实现构造器注入

1. @Autowired@Resource 注解

@Autowired
  • @Autowired 是 Spring 框架提供的注解,用于自动装配依赖。
  • 可以用于字段、构造函数和 setter 方法。
java 复制代码
@Autowired
private ISysUserService userService;
@Resource
  • @Resource 是 Java EE 提供的注解,Spring 也支持它,用于自动装配依赖。
  • 一般用于字段和 setter 方法。
java 复制代码
@Resource
private ISysUserService userService;

2. 构造函数注入

使用 Lombok 的 @RequiredArgsConstructor

springboot @RequiredArgsConstructor的概念与使用-腾讯云开发者社区-腾讯云 (tencent.com)

  • @RequiredArgsConstructor 是 Lombok 提供的注解,它会自动生成包含所有 final 字段的构造函数。
  • 使用构造函数注入可以确保依赖注入在对象创建时完成,确保所有依赖都是非空的。
java 复制代码
@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 字段
}

3. 比较和优点

字段注入(@Autowired@Resource
  • 优点:代码简洁,直接在字段上注解。
  • 缺点
    • 难以进行单元测试,因为需要通过反射或其他方式注入 mock 对象。
    • 依赖注入发生在对象创建之后,可能导致依赖未完全初始化的问题。
    • 违反了依赖倒置原则,类直接依赖于容器。
构造函数注入
  • 优点
    • 强制依赖在对象创建时就完全初始化,确保所有依赖非空。
    • 更容易进行单元测试,因为可以通过构造函数注入 mock 对象。
    • 更符合依赖倒置原则,使类更独立于容器。
    • 提升了代码的可读性和可维护性,尤其是当依赖较多时。
  • 缺点 :需要额外的构造函数代码,但使用 Lombok 的 @RequiredArgsConstructor 可以减轻这个负担。

4. 示例对比

使用 @Autowired
java 复制代码
@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;

    // 其他代码
}
使用构造函数注入
java 复制代码
@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;

    // 其他代码
}

通过这种构造函数注入的方式,不仅可以增强代码的健壮性和可维护性,还可以更好地利用 Spring 的依赖注入特性和 Lombok 的简化代码的优势。

好处

Spring的构造器注入_spring构造器注入-CSDN博客

5.关于注解

在使用构造函数注入时,不需要额外添加注解,只需要提供构造函数即可。Spring 会自动检测到你的构造函数并进行依赖注入。

使用构造函数注入,不需要额外注解
java 复制代码
@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. Spring 自动注入:
    • Spring 在创建 Bean 实例时,会自动识别并调用该构造函数,同时注入所需的依赖。

示例代码

java 复制代码
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;
    }

    // 你的控制器方法
}

在这个例子中,不需要使用任何额外的注解来标注构造函数,Spring 会自动识别并注入依赖。(当然,标注了也不会报错,但是只能使用@Autowired,不能使用@Resouce,@Resource 注解通常用于字段或 setter 方法注入)

额外情况
  1. 多个构造函数:
    • 如果一个类中有多个构造函数,并且其中只有一个构造函数有注入参数,Spring 会使用这个构造函数进行注入。
    • 如果有多个构造函数都有注入参数,则需要使用 @Autowired 注解来明确指定使用哪个构造函数。

示例代码(多个构造函数)

java 复制代码
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;
    }

    // 你的控制器方法
}

在这个例子中,由于存在多个构造函数,需要使用 @Autowired 注解来明确指定 Spring 使用哪个构造函数进行依赖注入。

相关推荐
Boilermaker19929 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
Cherry的跨界思维9 小时前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
alonewolf_9910 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
一嘴一个橘子10 小时前
spring-aop 的 基础使用(啥是增强类、切点、切面)- 2
java
sheji341610 小时前
【开题答辩全过程】以 中医药文化科普系统为例,包含答辩的问题和答案
java
恋爱绝缘体110 小时前
2020重学C++重构你的C++知识体系
java·开发语言·c++·算法·junit
wszy180911 小时前
新文章标签:让用户一眼发现最新内容
java·python·harmonyos
wszy180911 小时前
顶部标题栏的设计与实现:让用户知道自己在哪
java·python·react native·harmonyos
程序员小假12 小时前
我们来说一下无锁队列 Disruptor 的原理
java·后端
资生算法程序员_畅想家_剑魔12 小时前
Kotlin常见技术分享-02-相对于Java 的核心优势-协程
java·开发语言·kotlin