Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Spring @Autowired inject beans by name or by type?

Tags:

I am reading beginning spring (wiley press) book. In chapter 2 there is an example about Java configuration and @Autowired. It provides this @Configuration class

@Configuration public class Ch2BeanConfiguration {      @Bean     public AccountService accountService() {         AccountServiceImpl bean = new AccountServiceImpl();         return bean;     }      @Bean     public AccountDao accountDao() {         AccountDaoInMemoryImpl bean = new AccountDaoInMemoryImpl();         //depedencies of accountDao bean will be injected here...         return bean;     }      @Bean     public AccountDao accountDaoJdbc() {         AccountDaoJdbcImpl bean = new AccountDaoJdbcImpl();         return bean;     } } 

and this regular bean class

public class AccountServiceImpl implements AccountService {      @Autowired     private AccountDao accountDao;      public void setAccountDao(AccountDao accountDao) {         this.accountDao = accountDao;     }     ... } 

When I run the code, it works. But I expected an exception because I have defined 2 beans with the same type in the configuration.

I realized it works like this:

  • if Spring encounters multiple beans with same type it checks field name.
    • if it finds a bean with the name of the target field, it injects that bean into the field.

Isn't this wrong? Is there a bug in Spring's handling of Java configuration?

like image 203
Lidovic Avatar asked May 20 '15 21:05

Lidovic


People also ask

What type of injection is Autowired?

In case of byName autowiring mode, bean id and reference name must be same. It internally uses setter injection.

How Autowire identifies the bean type?

When autowiring a property in bean, the property's class type is used for searching a matching bean definition in the configuration file. If such a bean is found, it is injected into the property. If no such bean is found, an error is raised.

How do you auto inject into a Spring bean by its name?

D. By using the @Autowired annotation and naming the field with the bean name.


1 Answers

The documentation explains this

For a fallback match, the bean name is considered a default qualifier value. Thus you can define the bean with an id "main" instead of the nested qualifier element, leading to the same matching result. However, although you can use this convention to refer to specific beans by name, @Autowired is fundamentally about type-driven injection with optional semantic qualifiers. This means that qualifier values, even with the bean name fallback, always have narrowing semantics within the set of type matches; they do not semantically express a reference to a unique bean id

So, no, it's not a bug, that is the intended behavior. The bean id (name) will be used as a fallback if a by-type autowiring doesn't find a single matching bean.

like image 166
Sotirios Delimanolis Avatar answered Nov 04 '22 12:11

Sotirios Delimanolis