Card 06/ 07
Practice: Finding and Fixing an Ambiguous Bean
An application that will not start, two receipt printers, and the smallest change that fixes it.
An ambiguous dependency happens when more than one bean could fill a constructor parameter. The application below fails to start. Work out why, and name the smallest fix, before you open the answer.
interface ReceiptPrinter { void print(String text); }
@Component
class ThermalReceiptPrinter implements ReceiptPrinter { /* ... */ }
@Component
class EmailReceiptPrinter implements ReceiptPrinter { /* ... */ }
@Service
class CheckoutService {
CheckoutService(ReceiptPrinter printer) { /* ... */ }
}See the fix
Two beans implement ReceiptPrinter, and nothing tells CheckoutService which one to take: two candidates for one constructor parameter, and Spring will not guess between them. If thermal receipts are the default, add @Primary, which marks a bean as the one to use when several match, to ThermalReceiptPrinter. If CheckoutService specifically needs email, add @Qualifier("emailReceiptPrinter"), which names the exact bean a parameter wants, to its constructor parameter instead; that is the bean name Spring derives from the class name EmailReceiptPrinter. Deleting one of the two printers would also let the application start, but it removes a feature; either annotation keeps both printers available.
← → move through sections and cards