Spring @Primary Annotation

1. Overview

In this quick tutorial, we’ll discuss Spring’s @Primary annotation which was introduced with version 3.0 of the framework.

Simply put, we use @Primary to give higher preference to a bean when there are multiple beans of the same type.

Let’s describe the problem in detail.

2. Why Is @Primary Needed?

In some cases, we need to register more than one bean of the same type.

In this example we have JohnEmployee() and TonyEmployee() beans of the Employee type:

@Configuration
public class Config {

    @Bean
    public Employee JohnEmployee() {
        return new Employee("John");
    }

    @Bean
    public Employee TonyEmployee() {
        return new Employee("Tony");
    }
}

Spring throws NoUniqueBeanDefinitionException if we try to run the application.

To access beans with the same type we usually use @Qualifier(“beanName”) annotation.

We apply it at the injection point along with @Autowired. In our case, we select the beans at the configuration phase so @Qualifier can’t be applied here. We can learn more about @Qualifier annotation by following the link.

To resolve this issue Spring offers the @Primary annotation.

3. Use @Primary With @Bean

Let’s have a look at configuration class:

@Configuration
public class Config {

    @Bean
    public Employee JohnEmployee() {
        return new Employee("John");
    }

    @Bean
    @Primary
    public Employee TonyEmployee() {
        return new Employee("Tony");
    }
}

We mark TonyEmployee() bean with @Primary. Spring will inject TonyEmployee() bean preferentially over the JohnEmployee().

Now, let’s start the application context and get the Employee bean from it:

AnnotationConfigApplicationContext context
  = new AnnotationConfigApplicationContext(Config.class);

Employee employee = context.getBean(Employee.class);
System.out.println(employee);

After we run the application:

Employee{name='Tony'}

From the output, we can see that the TonyEmployee() instance has a preference while autowiring.

4. Use @Primary With @Component

We can use @Primary directly on the beans. Let’s have a look at the following scenario:

public interface Manager {
    String getManagerName();
}

We have a Manager interface and two subclass beans, DepartmentManager:

@Component
public class DepartmentManager implements Manager {
    @Override
    public String getManagerName() {
        return "Department manager";
    }
}

And the GeneralManager bean:

@Component
@Primary
public class GeneralManager implements Manager {
    @Override
    public String getManagerName() {
        return "General manager";
    }
}

They both override the getManagerName() of the Manager interface. Also, note that we mark the GeneralManager bean with @Primary.

This time, @Primary only makes sense when we enable the component scan:

@Configuration
@ComponentScan(basePackages="org.maixuanviet.primary")
public class Config {
}

Let’s create a service to use dependency injection while finding the right bean:

@Service
public class ManagerService {

    @Autowired
    private Manager manager;

    public Manager getManager() {
        return manager;
    }
}

Here, both beans DepartmentManager and GeneralManager are eligible for autowiring.

As we marked GeneralManager bean with @Primary, it will be selected for dependency injection:

ManagerService service = context.getBean(ManagerService.class);
Manager manager = service.getManager();
System.out.println(manager.getManagerName());

The output is “General manager”.

5. Conclusion

In this article, we learned about Spring’s @Primary annotation. With the code examples, we demonstrated the need and the use cases of the @Primary.

As usual, the complete code for this article is available over on GitHub project.

Related posts:

Spring Boot Integration Testing with Embedded MongoDB
Java Program to Implement Triply Linked List
Java Program to Compute Discrete Fourier Transform Using the Fast Fourier Transform Approach
Java Program to Implement the Alexander Bogomolny’s UnOrdered Permutation Algorithm for Elements Fro...
Hướng dẫn kết nối cơ sở dữ liệu với Java JDBC
Check If a File or Directory Exists in Java
Giới thiệu Aspect Oriented Programming (AOP)
Adding a Newline Character to a String in Java
Java Program to Implement Hash Tables chaining with Singly Linked Lists
Tìm hiểu về Web Service
Dockerizing a Spring Boot Application
Comparing Strings in Java
Tips for dealing with HTTP-related problems
Java Concurrency Interview Questions and Answers
Java Program to Implement CopyOnWriteArrayList API
Introduction to Liquibase Rollback
Concurrent Test Execution in Spring 5
Java Program to Implement Shell Sort
Java Program to Implement ArrayBlockingQueue API
Giới thiệu Java 8
Java Program to Implement Radix Sort
Java Program to Implement Graham Scan Algorithm to Find the Convex Hull
Java Program to Implement Pairing Heap
Java Program to Implement the One Time Pad Algorithm
Guide to System.gc()
Immutable ArrayList in Java
Spring REST API + OAuth2 + Angular
Các nguyên lý thiết kế hướng đối tượng – SOLID
The Registration API becomes RESTful
Java Web Services – Jersey JAX-RS – REST và sử dụng REST API testing tools với Postman
How to Remove the Last Character of a String?
Java Program to Perform Quick Sort on Large Number of Elements