从零开始 Spring Boot 38:Lombok 与依赖注入

这篇具有很好参考价值的文章主要介绍了从零开始 Spring Boot 38:Lombok 与依赖注入。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

从零开始 Spring Boot 38:Lombok 与依赖注入

从零开始 Spring Boot 38:Lombok 与依赖注入

图源:简书 (jianshu.com)

在之前的文章中,我详细介绍了 Lombok 的用法,考虑到在 Spring 中使用依赖注入(DI)是如此的频繁,因此有必要讨论使用 Lombok 时可能对依赖注入造成的影响。

我们都知道,Spring 中的依赖注入分为三种情况:

  • 通过属性进行依赖注入。
  • 通过构造器进行依赖注入。
  • 通过 Setter 进行依赖注入。

通过属性进行依赖注入并不会影响我们使用 Lombok,比如:

@RestController
@RequestMapping("/hello")
@Validated
@AllArgsConstructor
public class HelloController {
    @Autowired
    private FibonacciService fibonacciService;

    @GetMapping
    public Result<?> hello(@RequestParam @Min(1) @NotNull Integer n) {
        int fibonacci = fibonacciService.fibonacci(n);
        return Result.success(fibonacci);
    }
}

**无论我们有没有使用构造器注入,用@Autowired标记的属性都会在 bean 实例创建后被 Spring 通过反射来完成注入。**因此实际上这里 Lombok 的@AllArgsConstructor注解生成的构造器并不会对属性fibonacciService的注入产生影响。

构造器注入

下面我们看构造器注入时的情形。

一般的,我们可以将属性设置为final,并借助 Lombok 的@RequiredArgsConstructor注解对需要的属性进行构造器注入:

@RestController
@RequestMapping("/hello")
@Validated
@RequiredArgsConstructor
public class HelloController {
    private final FibonacciService fibonacciService;

    @GetMapping
    public Result<?> hello(@RequestParam @Min(1) @NotNull Integer n) {
        int fibonacci = fibonacciService.fibonacci(n);
        return Result.success(fibonacci);
    }
}

我们知道,在 Spring 的后期版本中,只有一个构造器的情况下是不需要用@Autowired来标记构造器的,Spring 默认会使用这个唯一的构造器进行注入。而在这个示例中,@RequiredArgsConstructor会为我们创建一个包含所有final的非静态属性的构造器,而 Spring 将用这个构造器完成注入。

我们看到,只有一个构造器时(无论是自己编写的还是 Lombok 自动生成的),都不会产生影响,但如果有多个构造器呢?

看下面这个示例:

@RestController
@RequestMapping("/hello")
@Validated
@RequiredArgsConstructor
public class HelloController {
    private final FibonacciService fibonacciService;
    private final Integer n;

    @Autowired
    public HelloController(FibonacciService fibonacciService) {
        this(fibonacciService, 10);
    }

    @GetMapping
    public Result<?> hello(@RequestParam String n) {
        int numN;
        if ("null".equals(n)) {
            numN = this.n;
        } else {
            numN = Integer.parseInt(n);
        }
        if (numN < 1) {
            return Result.fail("hello.input.invalid", "n 不能小于 1");
        }
        int fibonacci = fibonacciService.fibonacci(numN);
        return Result.success(fibonacci);
    }
}

在这个示例中,实际上字节码中会有两个构造器,一个是我们自己编写的有一个参数的构造器,另一个是 Lombok 生成的有两个参数的构造器。

注意,在自己编写的构造器中,我们使用this(...)调用了 Lombok 创建的构造器。

此时如果我们想通过构造器对属性fibonacciService进行注入,就需要告诉 Spring 框架该用哪个构造器完成注入。比较简单的是,如果要用于注入的构造器是我们自己编写的(就像示例中的),我们只需要使用@Autowired标记相应的构造器即可。

如果是反过来,就会有一点麻烦:

@RestController
@RequestMapping("/hello")
@Validated
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class HelloController {
    private final FibonacciService fibonacciService;
    private Integer n = 10;

    public HelloController(FibonacciService fibonacciService, Integer n) {
        this.fibonacciService = fibonacciService;
        this.n = n;
    }

	// ...
}

注意,这里的属性n被修改为非final的。

现在,@RequiredArgsConstructor(onConstructor = @__(@Autowired))将在HelloController类的字节码中生成一个带@Autowired标记的构造器用于注入:

@RestController
@RequestMapping({"/hello"})
@Validated
public class HelloController {
    // ...
    @Autowired
    public HelloController(final FibonacciService fibonacciService) {
        this.fibonacciService = fibonacciService;
    }
}

也就是说,我们可以在 Lombok 用于生成构造器的相应注解中,通过onConstructor属性来指定一系列注解,让 Lombok 在生成构造器时在构造器上添加上这些注解。

这种写法(@__(@Autowired)))有些奇怪,实际上@__是一个并不存在的注解,可以用它来包裹一个注解列表(逗号分隔)来为构造器指定多个用于生成时添加的注解。

Setter 注入

我们知道,在使用 Setter 注入时,必须要使用@Autowired注解。同样的,可以用类似的方式让 Lombok 生成 Setter 时添加上相应的注解:

@RestController
@RequestMapping("/hello")
@Validated
public class HelloController {
    @Setter(onMethod = @__(@Autowired))
    private FibonacciService fibonacciService;
    private final Integer n = 10;
    
    @GetMapping
    public Result<?> hello(@RequestParam String n) {
        // ...
    }
}

The End,谢谢阅读。

这篇文章相对来说简短很多,算是对之前的文章的一个补充。

本文所有的示例代码可以通过这里获取。文章来源地址https://www.toymoban.com/news/detail-481290.html

参考资料

  • Constructor Injection in Spring with Lombok | Baeldung

到了这里,关于从零开始 Spring Boot 38:Lombok 与依赖注入的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决Spring Boot单元测试中@Autowired依赖注入失效的问题

    本文介绍了在Spring Boot单元测试中使用@Autowired注入的方法中,由于使用反射导致依赖注入失效的问题,以及如何使用AutowiredAnnotationBeanPostProcessor手动处理依赖注入来解决这个问题。 在Spring Boot的单元测试中,我们经常使用@Autowired注解来自动注入需要测试的对象或依赖。然而,

    2024年02月03日
    浏览(55)
  • 从零开始学Spring Boot系列-SpringApplication

    SpringApplication类提供了一种从main()方法启动Spring应用的便捷方式。在很多情况下, 你只需委托给 SpringApplication.run这个静态方法 : 当应用启动时, 你应该会看到类似下面的东西: 默认情况下会显示INFO级别的日志信息, 包括一些相关的启动详情, 比如启动应用的用户等。 通过

    2024年04月08日
    浏览(62)
  • 从零开始学Spring Boot系列-集成Kafka

    Apache Kafka是一个开源的分布式流处理平台,由LinkedIn公司开发和维护,后来捐赠给了Apache软件基金会。Kafka主要用于构建实时数据管道和流应用。它类似于一个分布式、高吞吐量的发布-订阅消息系统,可以处理消费者网站的所有动作流数据。这种动作流数据包括页面浏览、搜

    2024年03月21日
    浏览(62)
  • 从零开始 Spring Boot 63:Hibernate 继承映射

    图源:简书 (jianshu.com) 关系型数据库设计中是不存在继承概念的,但实体类可以用继承来组织代码结构,所以需要用一种方式将实体类的继承结构映射到表结构。 本文将介绍几种在 JPA(Hibernate)中映射实体类继承层次的方式。 第一种方式是用 @MappedSuperclass 标记超类(Super

    2024年02月12日
    浏览(52)
  • 从零开始学Spring Boot系列-集成mybatis

    在Spring Boot的应用开发中,MyBatis是一个非常流行的持久层框架,它支持定制化SQL、存储过程以及高级映射。在本篇文章中,我们将学习如何在Spring Boot项目中集成MyBatis,以便通过MyBatis进行数据库操作。 首先,我们需要在项目中添加MyBatis的依赖。在Spring Boot中,我们通常会使

    2024年03月10日
    浏览(130)
  • Spring Boot(04):让你的Spring Boot应用“火力全开”,从零开始学习starter

            Spring Boot是一款非常流行的Java开发框架,其具有快速开发、自动化配置、内嵌服务器、易于扩展等特点,因此备受开发者欢迎。在日常开发中,我们经常需要在不同的环境中进行测试和部署,此时,如何实现开发、测试、生产环境的快速切换,成为了我们需要解决

    2024年04月13日
    浏览(61)
  • 从零开始 Spring Boot 52:@Embedded 和 @Embeddable

    图源:简书 (jianshu.com) 这篇文章会介绍 @Embedded 和 @Embeddable 两个注解在 JPA 中的用法。 先看一个示例: 这里使用了 Lombok 相关注解(比如 @Builder )帮助构建实体类,详细内容可以阅读我的相关文章。 user_student 是一个学生表,其中的 contacts_ 开头的字段保存联系人信息,这体

    2024年02月12日
    浏览(67)
  • 从零开始 Spring Boot 37:初始化 ApplicationContext

    图源:简书 (jianshu.com) 从前文可以知道,作为 Ioc 容器的 ApplicationContext,需要进行一系列步骤来初始化以最终就绪(对于 Web 应用来说就是可以提供Http服务)。 这些步骤大概可以分为以下内容: 准备上下文关联的 Environment 。 初始化 ApplicationContext( ApplicationContextInitializers

    2024年02月08日
    浏览(45)
  • 从零开始学Spring Boot系列-外部化配置

    Spring Boot 允许你将配置外部化,以便可以在不同的环境中使用相同的应用程序代码。可以使用属性文件、YAML文件、环境变量和命令行参数将配置外部化。属性值可以通过使用 @Value 注解直接注入 bean,可以通过 Spring 的 Environment 抽象访问,也可以通过 @ConfigurationProperties。 Sp

    2024年04月10日
    浏览(108)
  • 从零开始 Spring Boot 49:Hibernate Entity Lifecycle

    图源:简书 (jianshu.com) 本文将介绍 Hibernate 的 Session 接口,以及如何用 Session 的相关 API 转换实体(Entity)的生命周期状态。 如果缺少的 JPA 和 Hibernate 的基本认识,可以阅读前篇文章。 持久化上下文 在 JPA 的相关概念中,存在一个 持久化上下文 (Persistence Context)。 持久化

    2024年02月11日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包