Specifying an unique name for @Bean annotation is necessary if
- the configuration provides more than one implementations for a bean
- or if we want to inject bean instances by name rather than by type.
To match a named bean to an injection point (or in other words to qualify a bean to an injection point), the bean's property name (at the injection point) should match with the bean definition name.
Matching bean by using @Qualifier
Or another way to fix above exception is to use @Qualifier at both places:
Example
package com.logicbig.example.service;
public interface OrderService {
String getOrderDetails(String orderId);
}
package com.logicbig.example.service.impl;
import com.logicbig.example.service.OrderService;
public class OrderServiceImpl1 implements OrderService {
public String getOrderDetails(String orderId) {
return "Order details from impl 1, for order id=" + orderId;
}
}
package com.logicbig.example.service.impl;
import com.logicbig.example.service.OrderService;
public class OrderServiceImpl2 implements OrderService {
public String getOrderDetails(String orderId) {
return "Order details from impl 2, for order id=" + orderId;
}
}
Using @Qualifier at injection point
package com.logicbig.example.client;
import com.logicbig.example.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import java.util.Arrays;
public class OrderServiceClient {
@Autowired
@Qualifier("OrderServiceA")
private OrderService orderService;
public void showPendingOrderDetails () {
for (String orderId : Arrays.asList("100", "200", "300")) {
System.out.println(orderService.getOrderDetails(orderId));
}
}
}
Defining beans' name via @Bean#name
package com.logicbig.example;
import com.logicbig.example.client.OrderServiceClient;
import com.logicbig.example.service.OrderService;
import com.logicbig.example.service.impl.OrderServiceImpl1;
import com.logicbig.example.service.impl.OrderServiceImpl2;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppRunner {
@Bean(name = "OrderServiceA")
public OrderService orderServiceByProvider1() {
return new OrderServiceImpl1();
}
@Bean(name = "OrderServiceB")
public OrderService orderServiceByProvider2() {
return new OrderServiceImpl2();
}
@Bean
public OrderServiceClient createClient() {
return new OrderServiceClient();
}
public static void main(String... strings) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppRunner.class);
OrderServiceClient bean = context.getBean(OrderServiceClient.class);
bean.showPendingOrderDetails();
}
}
OutputOrder details from impl 1, for order id=100 Order details from impl 1, for order id=200 Order details from impl 1, for order id=300
Using @Qualifier
package com.logicbig.example;
import com.logicbig.example.client.OrderServiceClient;
import com.logicbig.example.service.OrderService;
import com.logicbig.example.service.impl.OrderServiceImpl1;
import com.logicbig.example.service.impl.OrderServiceImpl2;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppRunner2 {
@Bean
@Qualifier("OrderServiceA")
public OrderService orderServiceByProvider1() {
return new OrderServiceImpl1();
}
@Bean(name = "OrderServiceB")
public OrderService orderServiceByProvider2() {
return new OrderServiceImpl2();
}
@Bean
public OrderServiceClient createClient() {
return new OrderServiceClient();
}
public static void main(String... strings) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppRunner2.class);
OrderServiceClient bean = context.getBean(OrderServiceClient.class);
bean.showPendingOrderDetails();
}
}
OutputOrder details from impl 1, for order id=100 Order details from impl 1, for order id=200 Order details from impl 1, for order id=300
Example ProjectDependencies and Technologies Used: - spring-context 6.1.2 (Spring Context)
Version Compatibility: 3.2.3.RELEASE - 6.1.2 Version compatibilities of spring-context with this example: Versions in green have been tested.
- JDK 17
- Maven 3.8.1
|