In this post under Spring Core, I will explain with example the purpose of “@Primary” annotation.
When doing autowiring by type, there may be scenarios where two bean definitions can be considered for injection.
For example if we have below DAO class
package package26;
public class Dao {
private String daoName;
public Dao(String daoName) {
this.daoName = daoName;
}
@Override
public String toString() {
return this.daoName;
}
}
And we have a configuration class as below
package package26;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class Example26 {
@Autowired
private Dao dao;
@Bean
public Dao jmsDao() {
return new Dao("jmsDao");
}
@Bean
public Dao dbDao() {
return new Dao("dbDao");
}
public Dao getDao() {
return this.dao;
}
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Example26.class);
Example26 example = applicationContext.getBean(Example26.class);
System.out.println(example.getDao());
}
}
You can see that for private field “dao” of type “Dao” class, Spring framework can consider two bean definitions one with name “jmsDao” and another with name “dbDao”.
Spring framework will get confused, unable to decide which one to pick.
That is where “@Primary” annotation come to help.
It can be applied to only one bean definition method and Spring framework will always consider that to create an instance and inject it.
So in our example if I apply “@Primary” annotation to “jmsDao” bean definition method as shown below
package package26;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class Example26 {
@Autowired
private Dao dao;
@Bean
@Primary
public Dao jmsDao() {
return new Dao("jmsDao");
}
@Bean
public Dao dbDao() {
return new Dao("dbDao");
}
public Dao getDao() {
return this.dao;
}
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Example26.class);
Example26 example = applicationContext.getBean(Example26.class);
System.out.println(example.getDao());
}
}
From now on Spring framework will always consider “jmsDao” bean definition method to create an instance and inject it to private field “dao”
In this way we can use “@Primary” annotation.