当前位置: 首页 > article >正文

自定义注解

自定义注解 @MovieQualifier,它是基于 Spring 的 @Qualifier 注解之上的一个扩展。通过 元注解 和自定义属性(genreformat)来实现精确的依赖注入。


自定义注解的定义

@MovieQualifier 是一个 自定义的注解,它通过标注 @Qualifier 来继承了 @Qualifier 的功能,同时扩展了其能力。

@Target({ElementType.FIELD, ElementType.PARAMETER}) // 允许注解作用于字段或参数
@Retention(RetentionPolicy.RUNTIME)  // 运行时保留此注解
@Qualifier // 声明这是一个扩展自 @Qualifier 的注解
public @interface MovieQualifier {
    String genre();   // 定义一个名为 "genre" 的属性
    Format format();  // 定义一个名为 "format" 的枚举类型属性
}
解读代码:
  1. @Target:定义了注解可以作用的范围。在这里,允许 @MovieQualifier 用于字段(FIELD)和参数(PARAMETER)。
  2. @Retention:定义了注解的生命周期。在这里,RUNTIME 表明注解在运行时仍然保留,可供反射使用。
  3. @Qualifier:继承了 Spring 的 @Qualifier 特性,使这个注解可以参与 Spring 的依赖注入流程。
  4. 自定义属性
    • genre:一个字符串,用于描述电影的类型(如 “Action”、“Comedy”)。
    • format:一个枚举类型,用于描述电影的格式,比如是 2D、3D 等。

使用自定义 @MovieQualifier 的场景

我们可以用这个注解来标识特定的Bean,并在注入时通过提供对应的 genreformat 值来精确匹配。

示例:定义多个符合条件的Bean
import org.springframework.stereotype.Component;

@Component
@MovieQualifier(genre = "Action", format = Format.DIGITAL)
public class ActionDigitalMovie implements Movie {
    // Bean 示例
}

@Component
@MovieQualifier(genre = "Comedy", format = Format.DVD)
public class ComedyDvdMovie implements Movie {
    // Bean 示例
}

在这里,我们定义了两个实现类 ActionDigitalMovieComedyDvdMovie,并通过 @MovieQualifier 注解分别标注了 genreformat 的属性值。


示例:使用 @MovieQualifier 进行注入
public class MovieService {

    @Autowired
    @MovieQualifier(genre = "Action", format = Format.DIGITAL)
    private Movie actionMovie;

    @Autowired
    @MovieQualifier(genre = "Comedy", format = Format.DVD)
    private Movie comedyMovie;

    public void playMovies() {
        actionMovie.play();
        comedyMovie.play();
    }
}
运行时注入逻辑:
  1. Spring 会扫描到 @MovieQualifier 注解中的属性(如 genre = "Action"format = Format.DIGITAL)。
  2. 通过这些属性值,Spring 在容器中查找标识为 @MovieQualifier(genre = "Action", format = Format.DIGITAL) 的Bean。
  3. 匹配成功后,将对应的 ActionDigitalMovie 注入到 actionMovie 字段中。

为什么可以不带参数?

实际上 @MovieQualifier 本身的属性(genreformat)就是用于自定义精确匹配规则的参数。如果你省略了这些属性值,Spring 无法匹配到具体的Bean,会导致注入失败。

错误示例
@Autowired
@MovieQualifier // 没有参数,Spring 无法识别要注入的Bean
private Movie movie;

Spring 会抛出类似下面的异常:

No qualifying bean of type 'Movie' available: expected single matching bean but found 2.

原因是 @MovieQualifier 的属性(genreformat)是注解的 必填项,你必须提供它们的值,否则 Spring 无法辨别要注入哪个Bean。


如何改进?

如果确实希望 @MovieQualifier 能够不带参数,可以为其属性定义默认值。但请注意,这可能导致歧义,因为默认值可能与多个Bean匹配。

示例:为属性提供默认值
public @interface MovieQualifier {

    String genre() default "Action";  // 默认值为 "Action"
    Format format() default Format.DIGITAL;  // 默认值为 Format.DIGITAL
}
使用示例
@Autowired
@MovieQualifier // 没有参数,默认使用 genre = "Action", format = Format.DIGITAL
private Movie movie;

总结

  • 自定义 @MovieQualifier@Qualifier 的扩展版本,通过增加属性(如 genreformat),可以实现更精确的依赖注入。
  • 如果不带参数,Spring 无法通过 @MovieQualifier 的属性值匹配Bean,注入就会失败。
  • 可以通过为注解的属性设置默认值来支持不带参数的使用,但默认值可能会引起歧义,需要谨慎设计。

http://www.kler.cn/a/517943.html

相关文章:

  • 理解C++中的右值引用
  • hadoop==docker desktop搭建hadoop
  • @RabbitListener处理重试机制完成后的异常捕获
  • 电脑无法开机,重装系统后没有驱动且驱动安装失败
  • Spring WebFlux
  • MySQL(1)
  • tkinter绘制组件(44)——浮出ui控件
  • css-background-color(transparent)
  • 【玩转全栈】----Django基本配置和介绍
  • LeetCode题练习与总结:分糖果--575
  • 算法刷题Day27:BM65 最长公共子序列(二)
  • SpringCloud两种注册中心
  • 代码随想录刷题day14(2)|(链表篇)02.07. 链表相交(疑点)
  • 《网络安全中的“泛洪”攻击:揭秘、防范与应对策略》
  • TIM编码器接口函数及应用
  • 环境变量配置与问题解决
  • Gin 学习笔记
  • JAVA实战开源项目:在线旅游网站(Vue+SpringBoot) 附源码
  • 【Linux跬步积累】——thread封装
  • 使用Pytest Fixtures来提升TestCase的可读性、高效性
  • Java 实现Excel转HTML、或HTML转Excel
  • 「 机器人 」系统辨识实验浅谈
  • 如何有效进行软件集成测试?常见的集成测试工具分享
  • 工程数学速记手册(下)
  • 汽车免拆诊断案例 | 2007 款日产天籁车起步加速时偶尔抖动
  • 前端react后端java实现提交antd form表单成功即导出压缩包