DEV Community

MAYUR KUMBHAR
MAYUR KUMBHAR

Posted on

How @Autowired works in Spring - A detailed guide

In last post 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.


// 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;
}
Enter fullscreen mode Exit fullscreen mode

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.


@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.

Enter fullscreen mode Exit fullscreen mode

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.

@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;
}

Enter fullscreen mode Exit fullscreen mode

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.


Top comments (0)