In this tutorial, we will discuss on Spring’s @Primary annotation with examples, @Primary is available in Spring Framework since 3.0 version.
1. @Primary annotation in Spring
When there are multiple beans available of same type in Spring container, all of them are qualified to be autowired to single-valued dependency. That causes ambiguity and leads to throw an exception by framework. @Primary indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency.
There should be only one @Primary bean among same type of beans.
Let’s see an example.
package com.javabydeveloper.spring.primary; public class Animal { private String name; public Animal(String name) { this.name = name; } @Override public String toString() { return name; } }
@Configuration @ComponentScan("com.javabydeveloper.spring.primary") public class AppConfigForPrimary { @Bean public Animal tigerBean() { return new Animal("Tiger"); } @Bean @Primary public Animal kangarooBean() { return new Animal("Kangaroo"); } @Bean public Animal foxBean() { return new Animal("Fox"); } // ... Other beans }
package com.javabydeveloper.spring.primary; // ... public class PrimaryDITestBean { @Autowired private Animal animal; public void printAnimal() { System.out.println(animal); } // ... }
Testing :
public class ApplicationPrimaryDemo { public static void main(String[] args) { ApplicationContext ctxt = new AnnotationConfigApplicationContext(AppConfigForPrimary.class); PrimaryDITestBean pdits = ctxt.getBean(PrimaryDITestBean.class); pdits.printAnimal(); // ... } }
Output :
Kangaroo //...
2. Using @Primary with @Component
In previous example we have seen how to use @Primary with @Bean
. @Primary may be used on any class directly or indirectly annotated with @Component
class.
Let’s see an example.
package com.javabydeveloper.spring.primary; public interface DataService { public void printData(); }
package com.javabydeveloper.spring.primary; // ... @Component public class BinaryDataService implements DataService { @Override public void printData() { System.out.println("Binary Data"); } }
package com.javabydeveloper.spring.primary; // ... @Component @Primary public class TextDataService implements DataService { @Override public void printData() { System.out.println("Text Data"); } }
public class PrimaryDITestBean { // ... @Autowired private DataService dataService; public void printData() { dataService.printData(); } // ... }
Testing :
public class ApplicationPrimaryDemo { public static void main(String[] args) { ApplicationContext ctxt = new AnnotationConfigApplicationContext(AppConfigForPrimary.class); PrimaryDITestBean pdits = ctxt.getBean(PrimaryDITestBean.class); pdits.printData(); // ... } }
Output :
Text Data //...
3. Spring @Primary vs @Qualifier
3.1. We use @Qualifier in Spring to autowire a specific bean among same type of beans, where as @Primary is used to give high preference to the specific bean among multiple beans of same type to inject to a bean.
3.2. Suppose that you have provided multiple beans of same type and Spring is responsible to autowire a bean for that type (example: multiple datasources in single application), you need to tell Spring which bean should get autowired by default by annotating bean with @Primary, and we can not use @Qualifier in that situation because Spring will lookup for dependency in configuration phase.
3.3. We can use @Qualifier and @Primary for the same bean. Use @Qualifier to inject specific bean otherwise Spring injects bean by default which is annotated with @Primary.
Let’s see an example.
package com.javabydeveloper.spring.primary; public interface Bird { }
package com.javabydeveloper.spring.primary; public class Eagle implements Bird { @Override public String toString() { return "Eagle"; } }
public class Peacock implements Bird{ @Override public String toString() { return "Peacock"; } }
@Configuration @ComponentScan("com.javabydeveloper.spring.primary") public class AppConfigForPrimary { // ... @Bean @Primary @Qualifier("peacockBean") public Bird peacock() { return new Peacock(); } @Bean @Qualifier("eagleBean") public Bird eagle() { return new Eagle(); } }
public class PrimaryDITestBean { @Autowired @Qualifier("eagleBean") private Bird bird; // ... public void printBird() { System.out.println(bird); } }
Testing :
public class ApplicationPrimaryDemo { public static void main(String[] args) { ApplicationContext ctxt = new AnnotationConfigApplicationContext(AppConfigForPrimary.class); PrimaryDITestBean pdits = ctxt.getBean(PrimaryDITestBean.class); pdits.printBird(); // ... } }
Output :
Eagle // ...
Comment line @Qualifier("eagleBean")
in PrimaryDITestBean
class and test again.
Output :
Peacock // ...
4. Conclusion
In this quick tutorial we have seen how to use Spring’s @Primary annotation in Spring applications with examples.
You can get source code from our GitHub repository.
5. References
Other Related Tutorials: