Enterprise Java

Spring @Primary Annotation

Introduction:

Spring @Primary annotation is used to give a higher preference to the marked bean when multiple beans of the same type exist.

Spring, by default, auto-wires by type. And so, when Spring attempts to autowire and there are multiple beans of the same type, we’ll get a NoUniqueBeanDefinitionException:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException
  : No qualifying bean of type [com.programmergirl.Person]
  is defined: expected single matching bean but found 2: student, teacher
...

To solve this, we can choose to use Spring @Primary annotation, thereby marking one bean to be the primary one.

In this tutorial, we’ll explore the usage of this annotation in more detail.

@Primary In Configuration Class:

Let’s say we have the following configuration class:

@Configuration
public class UniversityConfig {
 
    @Bean
    @Primary
    public Person student() {
        return new Student();
    }
 
    @Bean
    public Person teacher() {
        return new Teacher();
    }
}

Both Teacher and Student beans inherit from Person and so we have marked it as the return type of both of our @Bean annotated method.

However, please note that we have marked the Student bean to be the primary one using @Primary annotation. Now, let’s start up our application:

AnnotationConfigApplicationContext context =
  AnnotationConfigApplicationContext(UniversityConfig.class);
 
Person student = context.getBean(Person.class);
System.out.println(student.getClass());

We’ll see that a Student object got a preference while Spring attempted autowiring.

Spring Component With @Primary:

Let’s say we instead have our component scan enabled:

@Configuration
@ComponentScan(basePackages="com.programmergirl.beans")
public class UniversityConfig {   
}

For such cases, we can directly annotate our Spring component class with @Primary:

@Primary
@Component
public class Student implements Person {
    ...
}
 
@Component
public class Teacher implements Person {
   ...
}

Now, when directly trying to inject a Person type without a @Qualifier, a Student bean will get injected:

@Service
public class StudentService {
 
    // Student bean is primary and so it'll get injected
    @Autowired
    private Person student;
 
    public void printStudentDetails() {
        System.out.println(student.getClass());
        ...
    }
}

Conclusion:

In this quick tutorial, we explored the usages of @Primary annotation in Spring.

As the name suggests, we can use @Primary annotation to define a primary one when having multiple beans of the same type.

Published on Java Code Geeks with permission by Shubhra Srivastava, partner at our JCG program. See the original article here: Spring @Primary Annotation

Opinions expressed by Java Code Geeks contributors are their own.

Shubhra Srivastava

Shubhra is a software professional and founder of ProgrammerGirl. She has a great experience with Java/J2EE technologies and frameworks. She loves the amalgam of programming and coffee :)
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button