Consider the following example:

    1. String color()
    2. }
    1. interface ColorPicker {
    2. fun color(): String
    3. }

    Given a common interface called ColorPicker that is implemented by multiple classes.

    The Primary Bean

    1. import io.micronaut.context.annotation.Primary;
    2. import javax.inject.Singleton;
    3. @Primary
    4. @Singleton
    5. class Green implements ColorPicker {
    6. @Override
    7. public String color() {
    8. return "green";
    9. }
    10. }

    The Primary Bean

    1. import io.micronaut.context.annotation.Primary
    2. import javax.inject.Singleton
    3. @Primary
    4. @Singleton
    5. class Green: ColorPicker {
    6. override fun color(): String {
    7. return "green"
    8. }

    The Green bean is a ColorPicker, but is annotated with @Primary.

    Another Bean of the Same Type

    1. @Singleton
    2. public class Blue implements ColorPicker {
    3. @Override
    4. public String color() {
    5. return "blue";
    6. }
    7. }
    1. import javax.inject.Singleton
    2. @Singleton
    3. class Blue implements ColorPicker {
    4. @Override
    5. String color() {
    6. return "blue"
    7. }
    8. }

    Another Bean of the Same Type

    The Blue bean is also a ColorPicker and hence you have two possible candidates when injecting the ColorPicker interface. Since Green is the primary it will always be favoured.

    1. @Controller("/testPrimary")
    2. public class TestController {
    3. protected final ColorPicker colorPicker;
    4. public TestController(ColorPicker colorPicker) { (1)
    5. @Get
    6. public String index() {
    7. return colorPicker.color();
    8. }
    9. }
    1. @Controller("/test")
    2. class TestController {
    3. protected final ColorPicker colorPicker
    4. TestController(ColorPicker colorPicker) { (1)
    5. this.colorPicker = colorPicker
    6. }
    7. @Get
    8. String index() {
    9. colorPicker.color()
    10. }
    11. }
    1. @Controller("/test")
    2. class TestController(val colorPicker: ColorPicker) { (1)
    3. @Get
    4. fun index(): String {
    5. return colorPicker.color()
    6. }

    If multiple possible candidates are present and no @Primary is defined then a will be thrown.