As we saw in Inject Spring Bean By Name example that if there are more than one instances available for an injection point then we have to use @Qualifier annotation to resolve ambiguity. As @Qualifier is used at injection point, there might be two situations where we don't want to or cannot use @Qualifier .
- Our autowiring mode is Autowire.BY_TYPE. Then of course we cannot use
@Qualifier because we actually don't have user defined injection point specified as @Autowired or @Inject
- We want to do bean selection (i.e. resolve the ambiguity) at configuration time rather than during beans development time.
The solution to above problems is to use @Primary annotation.
@Primary indicates that a particular bean should be given preference when multiple beans are candidates to be autowired to a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.
Example
In this example we are going to demonstrate how to use @Primary when autowiring mode is set to Autowire.BY_TYPE
package com.logicbig.example;
public interface Dao {
void saveOrder(String orderId);
}
package com.logicbig.example;
public class DaoA implements Dao {
@Override
public void saveOrder(String orderId) {
System.out.println("DaoA Order saved " + orderId);
}
}
package com.logicbig.example;
public class DaoB implements Dao {
@Override
public void saveOrder(String orderId) {
System.out.println("DaoA Order saved " + orderId);
}
}
package com.logicbig.example;
public class OrderService {
private Dao dao;
public void placeOrder(String orderId) {
System.out.println("placing order " + orderId);
dao.saveOrder(orderId);
}
public void setDao(Dao dao) {
this.dao = dao;
}
}
Definition beans and running the example
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class AppConfig {
@Bean(autowire = Autowire.BY_TYPE)
public OrderService orderService() {
return new OrderService();
}
@Bean
public Dao daoA() {
return new DaoA();
}
@Primary
@Bean
public Dao daoB() {
return new DaoB();
}
public static void main(String[] args) throws InterruptedException {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
OrderService orderService = context.getBean(OrderService.class);
orderService.placeOrder("122");
}
}
Outputplacing order 122 DaoA Order saved 122
Example ProjectDependencies and Technologies Used: - spring-context 5.3.23 (Spring Context)
Version Compatibility: 3.2.3.RELEASE - 5.3.23
- JDK 8
- Maven 3.8.1
|