☰ See All Chapters |
Spring @Primary Annotation
@Primary annotation is used to set the preference for same types of beans. Bean with @Primary annotation will be autowired when same types of beans are found. @Primary annotation can be used with @Bean, @Service, @Component and @Repository annotations.
Spring throws NoUniqueBeanDefinitionException when there are multiple beans resolved for same type. If Car is an interface and Audi, Ferrari are two different implementations of Car with both Audi and Ferrari annotated with @Component annotations, Spring throws NoUniqueBeanDefinitionException while creating application context. Spring has two different beans resolved for Car type. Suppose if Car variable is used with @Autowired annotation, spring has a conflict for injecting the bean. But we need both Audi and Ferrari implementation of Car. Solution for this is using @Qualifier annotation which we have read in our previous chapter Spring Qualifier Annotation. We can use Qualifier annotation if all code reside with us, but when code is delivered by another party in jar/war we cannot modify their code. If Car interface, Audi implementation and CarService is given by some third party and we made Ferrari implementation with the intention of using Ferrari implementation in our application we cannot set @Qualifier annotation to CarService. To handle this situation we can use @Primary annotation. Now we can use @Primary annotation with Ferrari class which resolves bean conflicts and spring uses Ferrari bean for injection.
Now let us see an example for @Primary annotation.
Spring @Primary Annotation Example
pom.xml
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.java4coding</groupId> <artifactId>Spring3_Primary</artifactId> <version>0.0.1-SNAPSHOT</version>
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
<properties> <spring.version>4.2.4.RELEASE</spring.version> </properties>
</project> |
Car.java
package com.java4coding.car;
public interface Car { public abstract void printCarName(); } |
Audi.java
package com.java4coding.car;
import org.springframework.stereotype.Component;
@Component public class Audi implements Car{
public void printCarName() { System.out.println("Audi"); } } |
Ferrari.java
package com.java4coding.car;
import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component;
@Component @Primary public class Ferrari implements Car{
public void printCarName() { System.out.println("Ferrari"); } } |
CarService.java
package com.java4coding.car;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
@Service public class CarService{
@Autowired Car car;
public Car getCar() { return car; }
public void setCar(Car car) { this.car = car; }
} |
SpringPrimaryAnnotationExample.java
package com.java4coding;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import com.java4coding.car.CarService;
@Configuration @ComponentScan(basePackages = { "com.java4coding.car" }) public class SpringPrimaryAnnotationExample {
public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext( SpringPrimaryAnnotationExample.class);
CarService carService = (CarService)ctx.getBean("carService"); carService.getCar().printCarName(); } } |
Output:
Without using @Primary annotation:
All Chapters