Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using @Qualifier and @Bean together in Java Config Spring

Tags:

spring

I have follow code

interface Drivable {

}

@Component
class Bmw implements Drivable {

}

@Component
class Mercedes implements Drivable {

}

class Driver {
    private Drivable drivable;

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

And Spring Java Config

@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();
    }
}

Can I use @Qualifier annotation with @Bean annotation if I want to specify type of object that should pass to method? I can't find in Spring doc how I can solve the problem. Thx.

like image 827
Andrew Valevskiy Avatar asked Mar 06 '18 09:03

Andrew Valevskiy


People also ask

Can we use @bean and @qualifier together?

NOTE: if you are creating bean with @Bean, it will be injected byType if there is duplicates then it will injected byName. we no need to mention @Bean(name="bmwDriver") . so you can directly use qualifier("bmwDriver") wherever you need in classes.

Can we use qualifier with Bean annotation?

One of the most important annotations in spring is @Qualifier annotation which is used to eliminate the issue of which bean needs to be injected.

Can we use @component and @bean in same class?

No. It is used to explicitly declare a single bean, rather than letting Spring do it automatically. If any class is annotated with @Component it will be automatically detect by using classpath scan. We should use @bean, if you want specific implementation based on dynamic condition.

Can we use @qualifier and @primary together?

We can use @Qualifier and @Primary for the same bean. Use @Qualifier to inject specific bean otherwise Spring injects bean by default which is annotated with @Primary.


1 Answers

I think you got the usage of @Qualifier bit wrong.

If we have more than one bean that qualifies for spring injection, then we use @Qualifer to specify which needs to be used for injection.

In this case you have two beans Bmw and Mercedes both implementing Drivable interface.

Presuming I got your intent correct, you want spring to inject Mercedes bean into the Driver object.

So for that, you need to specify public Driver getDriver(@Qualifier("mercedes") Drivable drivable) in the CarConfig class.

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

And then you can use AnnotationConfigApplicationContext to load the spring context and subsequently get the Driver bean as below:

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

Just to extend the example, let us say if you want to create a Driver bean for each of Bmw and Mercedes then the sample code would be:

@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);
    }
}
like image 199
Madhusudana Reddy Sunnapu Avatar answered Sep 28 '22 01:09

Madhusudana Reddy Sunnapu