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.
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.
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()); ... } }
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.
Hi! Thank you for making it simple.
Just discovered your site, found it on your description in Baeldung. I’m new to Spring so, simple is good.
Greetings from Stockholm 🙂
Glad it helped!😊