1

I'm new to Spring and Dependancy Injection, so I'll do my best, but this question may not be perfectly formed.

In short, imagine a 'sandwich' program that has a 'cheese' component. swiss cheese and provalone cheese both fit the interface, so they can both be used in our sandwich. Our code might look something like this.

class Sandwich{
   @Autowired
   Meat m;
   @Autowired
   Cheese c;
}

@Component
class Ham implements Meat{
}

@Component
class Swiss implements Cheese{
}

@Component
class Provolone implements Cheese{
}

It is obvious that spring framework will use ham as the meat; it’s the only meat component. But how does spring framework choose between Swiss and provolone? Is there some further setup required by the programmer? If so, how is this not tight coupling?

Thanks for the info! This enterprise level coding is new (and slightly intimidating) to me, so any input is appreciated.

jamesngyz
  • 503
  • 3
  • 11
jon P
  • 63
  • 2
  • 6

2 Answers2

1

This articles covers it well https://www.baeldung.com/spring-autowire#disambiguation

But in short, Spring follows the following steps:

  1. It will inspect the type of the field, then search the registered beans by type in the ApplicationContext. If there is only one qualifying bean, it will inject the bean
  2. Otherwise, it will attempt to disambiguate by looking at the variable name and if there is a qualifying bean with the same name and type, it will inject that bean
  3. Else, it will look for a @Qualifier annotation on the field. If there is an annotation, it will use the logic within to determine which bean to inject
  4. If it is still unable to resolve, Spring will throw an exception

I would suggest in your example either instantiate only one bean of type cheese. You can do this by annotating the classes with a @Profile annotation and use runtime profile values to select which one to instantiate.

Alternatively, you can declare List<Cheese> c and Spring will inject both cheeses into the variable as a List. Then you can choose which cheese to invoke during runtime from the List based on your business logic.

1
 In this case spring will give you the error as spring container have
 two object of type cheese that are Swiss and Provolone.
    
    class Sandwich{
       @autowired
       meat m;
       cheese c;
    }
    
    @component
    class Ham implements meat{
    }
    
    @component
    class Swiss implements cheese{
    }
    
    @component
    class Provolone implements cheese{
    }
    
    Now if you want to provide a particular cheese object to sandwich you can 
  add @Qualifier("swiss) or @Qualifier("provolone") onto the cheese object 
   (like to provide spring which object you have to refer).

  //Now asking springboot to refer swiss cheese in sandwich will be as follows.
    
    class Sandwich{
       @autowired
       meat m;
       @Qualifier("swiss")
       cheese c;
    }
    
    @component
    class Ham implements meat{
    }
    
    @component
    class Swiss implements cheese{
    }
    
    @component
    class Provolone implements cheese{
    }