Primary and Secondary Beans
Primary is a qualifier that indicates that a bean is the primary bean to be selected in the case of multiple interface implementations.
Consider the following example:
public interface ColorPicker {
String color();
}
interface ColorPicker {
String color()
}
interface ColorPicker {
fun color(): String
}
ColorPicker
is implemented by these classes:
The Primary Bean
import io.micronaut.context.annotation.Primary;
import jakarta.inject.Singleton;
@Primary
@Singleton
class Green implements ColorPicker {
@Override
public String color() {
return "green";
}
}
The Primary Bean
import io.micronaut.context.annotation.Primary
import jakarta.inject.Singleton
@Primary
@Singleton
class Green implements ColorPicker {
@Override
String color() {
return "green"
}
}
The Primary Bean
import io.micronaut.context.annotation.Primary
import jakarta.inject.Singleton
@Primary
@Singleton
class Green: ColorPicker {
override fun color(): String {
return "green"
}
}
The Green
bean class implements ColorPicker
and is annotated with @Primary
.
Another Bean of the Same Type
import jakarta.inject.Singleton;
@Singleton
public class Blue implements ColorPicker {
@Override
public String color() {
return "blue";
}
}
Another Bean of the Same Type
import jakarta.inject.Singleton
@Singleton
class Blue implements ColorPicker {
@Override
String color() {
return "blue"
}
}
Another Bean of the Same Type
import jakarta.inject.Singleton
@Singleton
class Blue: ColorPicker {
override fun color(): String {
return "blue"
}
}
The Blue
bean class also implements ColorPicker
and hence you have two possible candidates when injecting the ColorPicker
interface. Since Green
is the primary, it will always be favoured.
@Controller("/testPrimary")
public class TestController {
protected final ColorPicker colorPicker;
public TestController(ColorPicker colorPicker) { (1)
this.colorPicker = colorPicker;
}
@Get
public String index() {
return colorPicker.color();
}
}
@Controller("/test")
class TestController {
protected final ColorPicker colorPicker
TestController(ColorPicker colorPicker) { (1)
this.colorPicker = colorPicker
}
@Get
String index() {
colorPicker.color()
}
}
@Controller("/test")
class TestController(val colorPicker: ColorPicker) { (1)
@Get
fun index(): String {
return colorPicker.color()
}
}
1 | Although there are two ColorPicker beans, Green gets injected due to the @Primary annotation. |
If multiple possible candidates are present and no @Primary
is defined a NonUniqueBeanException is thrown.
In addition to @Primary
, there is also a Secondary annotation which causes the opposite effect and allows de-prioritizing a bean.