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. |