@RequiredArgsConstructor如何实现构造器注入
作者:しろいし
这篇文章主要介绍了@RequiredArgsConstructor如何实现构造器注入问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
@RequiredArgsConstructor实现构造器注入
1.@Autowired和@Resource 注解
@Autowired
@Autowired
是 Spring 框架提供的注解,用于自动装配依赖。- 可以用于字段、构造函数和 setter 方法。
@Autowired private ISysUserService userService;
@Resource
@Resource
是 Java EE 提供的注解,Spring 也支持它,用于自动装配依赖。- 一般用于字段和 setter 方法。
@Resource private ISysUserService userService;
2.构造函数注入
使用 Lombok 的 @RequiredArgsConstructor
springboot @RequiredArgsConstructor的概念与使用
@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 字段 }
3.比较和优点
字段注入(@Autowired
和 @Resource
)
优点:代码简洁,直接在字段上注解。
缺点:
- 难以进行单元测试,因为需要通过反射或其他方式注入 mock 对象。
- 依赖注入发生在对象创建之后,可能导致依赖未完全初始化的问题。
- 违反了依赖倒置原则,类直接依赖于容器。
构造函数注入
优点:
- 强制依赖在对象创建时就完全初始化,确保所有依赖非空。
- 更容易进行单元测试,因为可以通过构造函数注入 mock 对象。
- 更符合依赖倒置原则,使类更独立于容器。
- 提升了代码的可读性和可维护性,尤其是当依赖较多时。
缺点:
- 需要额外的构造函数代码,但使用 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; // 其他代码 }
使用构造函数注入
@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 的简化代码的优势。
好处
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.Spring 自动注入:
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; } // 你的控制器方法 }
在这个例子中,不需要使用任何额外的注解来标注构造函数,Spring 会自动识别并注入依赖。(当然,标注了也不会报错,但是只能使用@Autowired,不能使用@Resouce,@Resource
注解通常用于字段或 setter 方法注入)
额外情况
多个构造函数:
- 如果一个类中有多个构造函数,并且其中只有一个构造函数有注入参数,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; } // 你的控制器方法 }
在这个例子中,由于存在多个构造函数,需要使用 @Autowired
注解来明确指定 Spring 使用哪个构造函数进行依赖注入。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。