当前位置:   article > 正文

Spring注入还可以这样玩!涨知识了

Spring注入还可以这样玩!涨知识了

环境:Spring6.1.2


1. 简介

@Qualifier是 Spring 框架中的一个注解,它用于消除自动装配(autowiring)时的歧义。在 Spring 应用程序中,当存在多个相同类型的 bean 时,自动装配可能会产生歧义,因为 Spring 容器不知道该选择哪个 bean 进行注入。这时,我们可以使用 @Qualifier 注解来明确指定要注入的 bean。

假设你有两个 CommonDAO bean,每个都需要在不同的环境中使用。这时,你可以使用 @Qualifier 来指定具体的 bean。

public class CommonService {
  @Resource
  @Qualifier
  private CommonDAO dao ;
}
@Configuration
public class AppConfig {
  @Bean
  @Qualifier
  public TeacherDAO teacherDAO() {
    return new TeacherDAO() ;
  }
  @Bean
  public StudentDAO studentDAO() {
    return new StudentDAO() ;
  }
  @Bean
  public CommonService commonService() {
    return new CommonService() ;
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

上面示例中如果注入的CommonDAO字段上没有添加@Qualifier注解,那么程序将会报错,这里通过@Qualifier注解来限定注入的值;该注解也可以设置value属性。

2. 更多玩法

上面直接通过使用@Qualifier注解来限定注入值,接下来将介绍其它的使用方法。

2.1 自定义限定注解

@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Pack {
  String value();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

自定义限定注解,该注解上使用了@Qualifier注解。接下来我们就可以使用该注解。

public class CommonService {
  @Resource
  @Pack
  private CommonDAO dao ;
}
@Bean
@Pack
public TeacherDAO teacherDAO() {
  return new TeacherDAO() ;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这时候你就可以自定义不同的注解分别标准你要注入的值。

2.2 泛型限定注入

有如下接口定义,该接口是泛型接口

public class Teacher {}
public class Student {}
public interface CommonDAO<T> {}
public class TeacherDAO implements CommonDAO<Teacher> {}
public class StudentDAO implements CommonDAO<Student> {}
public class CommonService {
  @Resource
  private CommonDAO<Student> dao ;
  @Override
  public String toString() {
    return "CommonService [dao=" + dao + "]";
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在上面CommonDAO的注入中如果你泛型使用的Student那么注入的将是StudentDAO,如果是Teacher类型,那么注入的将是TeacherDAO。

泛型限定符也可用于List、Map 实例和数组。如下使用List示例:

@Resource
private List<CommonDAO<Student>> daos ;
  • 1
  • 2

这将注入容器中所有泛型是Student类型的CommonDAO实例对象。

2.3 完全自定义注解

有如下注解,我们完全可以不依赖任何Spring相关的注解实现限定的注入值。

@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Pack {
  String value() default "" ;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

该自定义注解并没有使用Spring的@Qualifier注解。要使得上面注解生效你还需要配置如下类

@Bean
public CustomAutowireConfigurer customAutowireConfigurer() {
  CustomAutowireConfigurer autowireConfigurer = new CustomAutowireConfigurer() ;
  // 指定我们自定义的注解
  autowireConfigurer.setCustomQualifierTypes(Set.of(Pack.class)) ;
  return autowireConfigurer ;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

CustomAutowireConfigurer是BeanFactoryPostProcessor,这会帮助我们注册自定义的限定注解。

2.4 更多属性控制

除了上面的方式限定注入的值,我们还可以自定义注解,指定更多的属性值去匹配bean对象,只有bean对象具有相同的属性值(元数据信息)才能匹配。

public enum Format {
  JSON, CSV, PLAIN
}
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Pack {
  String value() default "" ;
  // 指定格式
  Format format() ;
}
// Bean定义指定每一种bean对应的格式format
@Pack(format = Format.CSV)
public class CSVDAO implements CommonDAO {}
@Pack(format = Format.JSON)
public class JSONDAO implements CommonDAO {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

接下来在注册上面两个*DAO bean时就不能通过注解的方式了,只能通过xml或者BeanDefinition的方式注册,如下示例:

ApplicationContext context = ... ;
// 分别设置他们的元数据信息。
context.registerBean(CSVDAO.class, bd -> {
  bd.setAttribute("format", "CSV") ;
});
context.registerBean(JSONDAO.class, bd -> {
  bd.setAttribute("format", "JSON") ;
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

注入配置

@Resource
@Pack(format = Format.JSON)
private CommonDAO dao ;
  • 1
  • 2
  • 3

通过上面指定format属性,以确定需要注入对象的明确要求。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/1006494
推荐阅读
相关标签
  

闽ICP备14008679号