Spring @Primary Annotation Example

By Arvind Rai, November 11, 2021
This page will walk through Spring @Primary annotation example.
1. The @Primary annotation is used to make a bean preferable when multiple beans are qualified to autowire a single-valued dependency.
2. When there is more than one bean for dependency injection, we see the error as “expected single matching bean but found n”. Such type of error can be avoided just by using @Primary annotation at any preferable bean.
3. The @Primary annotation is used with @Bean, @Component and @Service annotations.
4. The @Primary annotation is equivalent to <bean> element's primary attribute in XML configuration.
5. The @Primary annotation is introduced in Spring 3.0.

Using @Primary with @Component

Here we have an interface and its two implementation classes.
Animal.java
package com.concretepage;
public interface Animal {
	void displayName();
} 
Lion.java
package com.concretepage;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
public class Lion implements Animal {
	@Override
	public void displayName() {
		System.out.println("--- Lion ---");
	}
} 
Tiger.java
package com.concretepage;
import org.springframework.stereotype.Component;
@Component
public class Tiger implements Animal {
	@Override
	public void displayName() {
		System.out.println("-- Tiger ---");
	}
} 
The @Primary annotation has been marked with @Component at Lion class.
Now create a service to autowire the Animal object.
AnimalService.java
package com.concretepage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AnimalService {
	private Animal animal;
	public Animal getAnimal() {
		return animal;
	}
	@Autowired
	public void setAnimal(Animal animal) {
		this.animal = animal;
	}
} 
We see that both Lion and Tiger beans are qualified to autowire for animal parameter. But the Lion will be injected because it is annotated with @Primary annotation at class level.
AppConfig.java
package com.concretepage;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages="com.concretepage")
public class AppConfig {
} 
SpringDemo.java
package com.concretepage;
import java.sql.SQLException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringDemo {
	public static void main(String[] args) throws SQLException {
	    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
	    ctx.register(AppConfig.class);
	    ctx.refresh();
	    Animal animal = ctx.getBean(Animal.class);
	    animal.displayName();
    	    ctx.registerShutdownHook();
	}
}  
Output:

Case 1. As we have used @Primary annotation on Lion bean. This will be selected for dependency injection. Find the output.
--- Lion --- 
Case 2. If we do not provide @Primary annotation on any bean, we will get error.
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.concretepage.Animal] is defined: expected single matching bean but found 2: lion,tiger
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054) 
Case 3. If we provide @Primary annotation on both the beans, we will get error.
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.concretepage.Animal] is defined: more than one 'primary' bean found among candidates: [lion, tiger]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.determinePrimaryCandidate(DefaultListableBeanFactory.java:1183) 

Using @Primary with @Bean

Find the code to use @Primary annotation with @Bean.
AppConfig.java
@Configuration
public class AppConfig {
  @Primary
  @Bean
  public Animal lion() {
	return new Lion();
  }

  @Bean
  public Animal tiger() {
	return new Tiger();
  }
} 

Reference

Annotation Type Primary

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us