在Java Config Spring中一起使用@Qualifier和@Bean

时间:2018-03-06 09:04:51

标签: spring

我已按照代码

FALSE

和Spring Java Config

   interface Drivable{

}

@Component
class Bmw implements Drivable {

}

@Component
class Mercedes implements Drivable {

}

class Driver {
    private Drivable drivable;

    public Driver(Drivable drivable) {
        this.drivable = drivable;
    }
}

如果我想指定应传递给方法的对象类型,是否可以将@Configuration @ComponentScan class CarConfig { @Bean @Qualifier("mercedes")//the code won't work public Driver getDriver(Drivable drivable) { return new Driver(drivable); } @Bean//I've added the bean public Drivable getMercedes() { return new Mercedes(); } } 注释与@Qualifier注释一起使用?我在Spring doc中找不到如何解决问题。 THX。

2 个答案:

答案 0 :(得分:2)

我认为您使用@Qualifier位错了。

如果我们有多个符合弹簧注射条件的bean,那么我们使用@Qualifer来指定哪些需要用于注射。

在这种情况下,您有两个bean BmwMercedes都实现了Drivable接口。

假设我的意图是正确的,你希望spring将Mercedes bean注入Driver对象。

因此,您需要在public Driver getDriver(@Qualifier("mercedes") Drivable drivable)类中指定CarConfig

@Configuration
@ComponentScan
class CarConfig {
    @Bean
    public Driver getDriver(@Qualifier("mercedes") Drivable drivable) {
        return new Driver(drivable);
    }

然后您可以使用AnnotationConfigApplicationContext加载spring上下文,然后获取Driver bean,如下所示:

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(CarConfig.class);
        Driver bean = ctx.getBean(Driver.class);
    }
}

为了扩展示例,我们假设您要为DriverBmw中的每一个创建Mercedes bean,那么示例代码将为:

@Configuration
@ComponentScan
class CarConfig {
    @Bean(name="mercedesDriver")
    public Driver getMercedesDriver(@Qualifier("mercedes") Drivable drivable) {
        return new Driver(drivable);
    }

    @Bean(name="bmwDriver")
    public Driver getBmwDriver(@Qualifier("bmw") Drivable drivable) {
        return new Driver(drivable);
    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(CarConfig.class);
        System.out.println(Arrays.asList(ctx.getBeanNamesForType(Driver.class)));
        Driver mercedesBean = ctx.getBean("mercedesDriver", Driver.class);
        Driver bmwBean = ctx.getBean("bmwDriver", Driver.class);
    }
}

答案 1 :(得分:0)

您可以为接口Drivable的每个特定实现定义限定符。完成后,现在您可以将它们自动连接到CarConfig类中,并且必须为每个Drivers(Mercedz和Benz)以及限定符名称创建Bean。

查找以下实现:

 @Target({ElementType.FIELD, ElementType.PARAMETER})
 @Retention(RetentionPolicy.RUNTIME)
 @Qualifier
 public @interface Bmw {
 }

 @Target({ElementType.FIELD, ElementType.PARAMETER})
 @Retention(RetentionPolicy.RUNTIME)
 @Qualifier
 public @interface Mercedes {
 }

现在您的驱动程序接口实现应使用以下限定符进行注释

@Compoenent
@Bmw
public interface Bmw implements Drivable{
}

@Component
@Mercedes
public interface Mercedes implements Drivable{
}

您的CarConfig类应如下所示:

@Configuration
public class CarConfig{

@autowire
@Bmw
private Drivable bmwDriver;

@autowire
@Mercedes
private Drivable mercedesDriver;


@Bean
public Bean getBmwDriver(){
  return new Bmw(bmwDriver);
  }

 @Bean
public Bean getMercedesDriver(){
   return new Mercedes(mercedesDriver);
  }

 }

注意:如果使用@Bean创建bean,那么如果有重复项,它将被type注入,然后将byName注入。我们无需提及@Bean(name =“ bmwDriver”)。 因此您可以在类中需要的任何地方直接使用qualifier(“ bmwDriver”)。