In this quick article, we’ll discuss Spring’s @Primary annotation which was introduced with version 3.0 of the framework.
Simply put, we use @Primary to give higher preference to a bean when there are multiple beans of the same type.
Let’s describe the problem in detail.
Why is @Primary Needed?
In some cases, we need to register more than one bean of the same type.
In this example we have mySQLConnection() and oracleConnection() beans of the Connection type:
@Configuration
public class Config {
@Bean
public Connection mySQLConnection() {
return new MySQLConnection();
}
@Bean
public Connection oracleConnection() {
return new OracleConnection();
}
}
Spring throws NoUniqueBeanDefinitionException if we try to run the application.
To access beans with the same type we usually use @Qualifier(“beanName”) annotation.
We apply to at the injection point along with @Autowired. In our case, we select the beans at the configuration phase so @Qualifier can’t be applied here. We can learn more about @Qualifier annotation by following the link.
To resolve this issue Spring offers the @Primary annotation. The following example shows how to use @Primary annotation in a spring application.
The @Primary annotation may be used on any class directly or indirectly annotated with @Component or on factory methods annotated with @Bean. In this example, we will use @Primary annotation with @Component annotation.
Spring @Primary Annotation Example
Let's create an example to demonstrates usage of use @Primary annotation in a spring application.
Tools and technologies used
- Spring Framework - 5.1.0.RELEASE
- JDK - 8 or later
- Maven - 3.2+
- IDE - Eclipse Mars/STS
Create a Simple Maven Project
Create a simple maven project using your favorite IDE and refer below section for packaging structure. If you are new to maven then read this article How to Create a Simple Maven Project.
Project Structure
Below diagram shows a project structure for your reference -
The pom.xml File
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.javaguides.spring</groupId>
<artifactId>spring-primary-annotation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-scope-example</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Next, consider the following MessageService interface.
MessageService.java
package net.javaguides.spring.primary;
public interface MessageService {
public void sendMsg();
}
Create three beans named as FacebookMessageService, EmailMessageService, and TwitterMessageService, which implement the MessageService interface.
FacebookMessageService.java
package net.javaguides.spring.primary;
import org.springframework.stereotype.Component;
@Component
public class FacebookMessageService implements MessageService {
@Override
public void sendMsg() {
System.out.println("FacebookMessageService implementation here");
}
}
EmailMessageService.java
package net.javaguides.spring.primary;
import org.springframework.stereotype.Component;
@Component
public class EmailMessageService implements MessageService {
@Override
public void sendMsg() {
System.out.println("EmailMessageService Implementation here");
}
}
TwitterMessageService.java
package net.javaguides.spring.primary;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Primary
@Component
public class TwitterMessageService implements MessageService {
@Override
public void sendMsg() {
System.out.println("TwitterMessageService Implementation here");
}
}
Note that in the above TwitterMessageService class we have added @Primary with @Component annotation.
Annotation Based Configuration - AppConfig.java
package net.javaguides.spring.primary;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "net.javaguides.spring.primary")
public class AppConfig {
}
Running Spring Application - Application.java
Let's create a main class and run an application.
package net.javaguides.spring.primary;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Application {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MessageService messageService = context.getBean(MessageService.class);
messageService.sendMsg();
context.close();
}
}
Output
TwitterMessageService Implementation here
The source code of this article is available on my GitHub repository https://github.com/RameshMF/spring-core-tutorial
Free Spring Boot Tutorial | Full In-depth Course | Learn Spring Boot in 10 Hours
Watch this course on YouTube at Spring Boot Tutorial | Fee 10 Hours Full Course
Comments
Post a Comment