April 14, 2022

Exclude Bean From Autowiring in Spring

If you want to exclude bean from autowiring in Spring on a per-bean basis then in Spring’s XML format it can be done by setting autowire-candidate attribute of the <bean/> element to false. The Spring container makes that specific bean definition unavailable for autowiring (that is applicable to annotation style configurations such as @Autowired too).

Excluding bean in autowiring - autowire-candidate example

In the example there is a class to place order called OrderService and purchase can be done from a Store. In OrderService class dependency for store has to be autowired.

There are two classes of type IStore and you want to exclude one of the bean from autowiring so that NoUniqueBeanDefinitionException is not thrown.

public interface OrderService {
  public void buyItems();
}
import org.springframework.beans.factory.annotation.Autowired;

public class OrderServiceImpl implements OrderService {
  private IStore store;
  @Autowired
  public OrderServiceImpl(IStore store){
    this.store = store;
  }
  public void buyItems() {
    store.doPurchase();
  }
}

As you can see here OrderServiceImpl class has a dependency of type Istore which is autowired as a constructor argument.

public interface IStore {
  public void doPurchase();
}
public class RetailStore implements IStore {
  public void doPurchase() {
    System.out.println("Doing purchase from Retail Store");
  }
}
public class OnlineStore implements IStore {
  public void doPurchase() {
    System.out.println("Doing purchase from Online Store");
  }
}
XML Configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context.xsd">
    
  <context:annotation-config/>      
  <!-- Store bean -->
  <bean id="retailStore" class="com.knpcode.springproject.service.RetailStore" />

  <!-- Store bean -->
  <bean id="onlineStore" class="com.knpcode.springproject.service.OnlineStore" autowire-candidate="false" />

  <!-- OrderServiceImpl bean with store bean dependency -->
  <bean id="orderBean" class="com.knpcode.springproject.service.OrderServiceImpl" />
</beans>

In the bean definition for onlineStore, autowire-candidate attribute is set as false so that this bean is excluded from autowiring.

By excluding one of the bean NoUniqueBeanDefinitionException is avoided which would have been thrown if there are multiple beans of the same type. You can can check by removing autowire-candidate="false" from the definition of onlineStore bean.

Error creating bean with name 'orderBean' defined in class path resource [appcontext.xml]: 
Unsatisfied dependency expressed through constructor parameter 0; 
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type 'com.knpcode.springproject.service.IStore' available: 
expected single matching bean but found 2: retailStore,onlineStore

There are other ways for conflict resolution while autowiring, check Spring Autowiring Using @Autowired Annotation for seeing how to do it using @Primary and @Qualifier annotations.

That's all for the topic Exclude Bean From Autowiring in Spring. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment