Close

Spring - Using @Primary annotation

[Last Updated: Dec 5, 2020]

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.

  1. 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
  2. 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");

  }
}

Output

placing order 122
DaoA Order saved 122

Dependencies and Technologies Used:

  • Spring Context 4.2.3.RELEASE: Spring Context.
  • JDK 1.8
  • Maven 3.0.4

Spring - @Primary annotation example Select All Download
  • spring-primary-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • AppConfig.java

    See Also