繁体   English   中英

Spring中@Qualifier的优势是什么?

[英]What is the advantage of @Qualifier in Spring?

假设我们有两个接口的实现:

@Component
public class Toyota implements Car {}

@Component
public class Bmw implements Car {}

使用@Qualifier有什么好处

@Autowired
@Qualifier("toyota")
private Car car;

自动装配时过度使用特定的实现类型?

@Autowired
private Toyota car;

我在这里看到的@Qualifier的缺点是失去了“类型安全”,因为它依赖于一个可能与 bean(类)名称不同步的字符串。

如何避免这种脆弱性? @Qualifier的优势是什么?

除了@Component之外,还有其他方法可以创建 bean。 考虑:

@Configuration
public class CarConfig {
    @Bean
    public Toyota first() {
        return new Toyota(1);
    }

    @Bean
    public Toyota second() {
        return new Toyota(2);
    }
}

在这种情况下,您无法通过选择更具体的类型来消除歧义的第二个示例。 使用命名限定符是 select 在这两者之间的唯一方法。

您也可能不希望客户端 class 了解您的接口的具体实现。 它可能会鼓励客户 class 使用不属于 Car 接口的 Toyota 的 API 的方法。 依赖这些方法会增加耦合,并可能使以后更难将实现换成不同的实现。

下面的方法怎么样:

public final class CarTypes {
    private CarTypes() {}
    public static final String TOYOTA = “toyota”;
    public static final String BMW = “bmw”;
}
public interface Car {...}

public class Toyota implements Car {...}
public class BMW implements Car {...}


@AllArgsConstructor
public class CarFactory { // or whatever that uses the car 
   private final Car car;
}

和 spring 配置:

static import CarTypes.*;
@Configuration
public class MyConfig {

   @Bean(name = TOYOTA)
   public Car toyotaWhateverMethod() { return new Toyota();}
    @Bean(name = BMW) 
    public Car bmwWhateverMethod() {return new BMW();}
    @Bean
    public CarFactory toyotaCarFactory(@Qualifier(TOYOTA) Car car) {
        return new CarFactory(car); 
    } 
          
}

请注意,类本身根本不带有任何注释,并且在配置中您始终依赖于静态导入的 class CarTypes的最终字段

它允许您对接口而不是实现进行编程。 请参阅this ,了解为什么对接口进行编程是好的。

所以如果你编程到一个接口,你应该自动连接到一个接口而不是一个实现,如果你有多个 bean 实现相同的接口,@ @Qualifier用于指定要注入的 bean。

我在这里看到通过依赖可能与 bean(类)名称不同步的字符串而失去“类型安全”。 如何避免这种脆弱性?

您可以简单地在@Component中显式配置 bean 名称,而不是依赖默认的 bean 名称派生自 class 名称。 为 bean 名称设置一个常量,并确保需要访问它的所有代码都应该通过这个常量访问:

@Component(Toyota.BEAN_NAME)
public class Toyota implements Car {
  public static final String BEAN_NAME = "MyToyota";
}
@Autowired
@Qualifier(Toyota.BEAN_NAME)
private Car car;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM