How @Autowired works in Spring - A detailed guide
Tags: springboot, spring, java
Published: 2023-06-19 14:53:09

In [last post](https://dev.to/themayurkumbhar/wiring-in-spring-51lc) we have seen how `@Autowired` can be used at multiple places to inject the dependent beans. Spring framework handles the dependency between the components and based on field, setter or constructor injection injects appropriate objects.

## Issue?

What happens when spring context has multiple beans of same type? which object spring framework injects for `@Autowired` annotation?

If we have single bean of required type in the spring context, there is no ambiguity to framework and it will inject the dependent bean wherever required.

## How Spring framework handle such scenarios?

When spring framework gets into situation of multiple beans of same type which need to be injected in one of the `@Autowired` dependency, it will follow the `three` steps to resolve the ambiguity.

> By Default IoC container will always look for `class type` of bean to inject.

### Step 1: look for bean name with same parameter/field name.

Spring IoC container will look for bean name with equal to parameter name mentioned with `@Autowired` annotation in filed, setter parameter, constructor parameter.

```java 

// field injection
@Autowired 
private SomeBean bean; // here spring looks for bean with name "bean" in context

// setter injection
@Autowired 
public void setSomeBean(SomeBean bean1){ // here spring looks for bean with name "bean1" in context to inject.
  this.bean = bean1;
}

// constructor injection
@Autowired 
public Example(SomeBean bean2){ // here spring looks for bean with name "bean2" in context to inject.
   this.bean=bean2;
}
```

> if no matching name bean found, follow step 2

### Step 2: Spring IoC container looks for bean marked as `@Primary` bean 

So if no matching name bean found, then spring IoC Container check for if there is any bean among multiple beans which is marked as `@Primary` bean, if yes inject that bean.

```java

@Primary // this is primary bean
@Bean 
public SomeBean myBean(){
  return new SomeBean("Hello");
}

@Bean // this is normal bean
public SomeBean myOtherBean(){
  return new SomeBean("Welcome");
}

// when @Autowired is invoked, as we have multiple beans of same class type, @Primary bean will be injected for below wiring.

@Autowired 
public SomeBean bean; // as no name bean matching with myBean, myOtherBean so Primary bean will be injected here.

```

> If no `@Primary` bean found in context, follow step 3

### Step 3: Spring IoC container will look for @Qualifier annotation and find the bean with name matching.

Now, IoC container checks if `@Qualifier` is used or not and if found look for the name of the bean mentioned in `@Qualifier` and injects that.

```java
@Bean 
public SomeBean myBean(){
  return new SomeBean("Hello");
}

@Bean
public SomeBean myOtherBean(){
  return new SomeBean("Welcome");
}

// when @Autowired is invoked, as we have multiple beans of same class type, @Primary bean not found checks name with @Qualifier and injects below

@Autowired // here qualifier used is "myBean" so IoC will inject the bean with name myBean
public Example(@Qualifier("myBean")SomeBean bean){ 
   this.bean = bean;
}

```

> Use of @Qualifier is beneficial as the parameter name can change based on developers choice to improve readability of code, but it will not impact the autowiring due to qualifier name used.


If all the above step followed and no matching bean is found then it will throw an exception `NoUniqueBeanDefinitionException` as multiple beans are present but are ambiguious.

---


<meta name="keywords" content="Autowiring, Dependency Injection, Spring Framework, Bean Wiring, Inversion of Control, Component Scanning, Constructor Injection, Setter Injection, Autowired Annotation, Bean Configuration, Spring Bean Lifecycle, Qualifiers and Primary Beans, Autowire by Type, Autowire by Name, Autowire by Qualifier, Autowire by Annotation, Autowire vs. Explicit Wiring, Benefits of Autowiring, Common Autowiring Pitfalls">