Autowiring By Type – @Primary

Spring autowire dynamically the dependencies, but how Spring do that, well, we already review in Managing beans and dependencies how Spring create the beans nad how they are handled. Now, let’s review how Spring handles the dynamic autowiring.

The dynamic autowiring occurs when Spring have more of one components of the same type. In the CoffeShop project we manage two beans: MakeCoffeeImplementation and LatteCoffee. What happens if we add another component of the Coffee type?. To response this question we will get a message like this:

2023-06-30 19:51:31.901 WARN 5754 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'makeCoffeeImplementation': Unsatisfied dependency expressed through field 'coffee'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.programmingsquirrel.coffeeshop.impl.Coffee' available: expected single matching bean but found 2: latteCoffee,mochaCoffee

We got an exception NoUniqueBeanDefinitionException, because Spring doesn’t know which bean inject, because both beans are candidates to be injected into the depency.

Spring will throws an NoUniqueBeanDefinitionException exception because Spring doesn’t know which bean inject.

To explain this let’s work with the CoffeShop project, this project we use it in Managing beans and dependencies. In project we will create a package called primary under com.programmingsquirrel.coffeeshop. and we will copy all the files and subpackages and paste it in the primary package. After copy all the files we create a new bean MochaCoffee of type Coffee, and mark the class as @Component.

package com.programmingsquirrel.coffeeshop.primary.impl;
import org.springframework.stereotype.Component;

@Component
public class MochaCoffee implements Coffee {
@Override
public void prepareCoffee() {
    System.out.println("Making a Mocha...");
}
}

The project must look like this.

One way in which Spring can choose between two beans (or more) of the same type is using the @Primary annotation.

@Primary

This @Primary annotation is used for mark a component as the default choice when we have multiple beans of the same type, and all are possible choices. In the LatteCoffe class we add the @Primary annotation below of the @Component annotation. now if we run the class com.programmingsquirrel.coffeeshop.primary.MakeCoffeeImplementation the application will run without any problems.

The use of @Primary anotation in Spring to indicate which bean will be the default bean to inject is know as autowiring by Type.

If we mark the other bean MochaCoffe with the @Primary annotation we will get an NoUniqueBeanDefinitionException exception, because again SPring don’t know which implementation use.

If we want to change the implementation we only need to change the bean that will use the @Primary annotation, making this the dynamic autowire.

This is the first option to perform the dynamic autowire, Spring handles another two options by Name and using the @Qualifier anotation.

Thanks for Reading and Happy Learning!!!

Leave a comment