Home Spring Framework Spring @Primary Annotation

Spring @Primary Annotation

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.

Satish Varma
Satish Varmahttps://javabydeveloper.com
Satish is post graduated in master of computer applications and experienced software engineer with focus on Spring, JPA, REST, TDD and web development. Follow him on LinkedIn or Twitter or Facebook

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Stay in Touch

Subscribe

Subscribe for latest updates.

 

Loading

Categories