Note that @Bean#autowire attribute was deprecated in version 5.1, that was because @Bean factory method argument resolution and @Autowired processing supersede name/type-based bean property injection. In Spring 6.x this attribute has been completely removed.
In this autowiring mode, Spring walks through type of each 'property' (the standard Java Bean property) of a given bean to match other registered beans type. If there's a match then the dependency injection happens. So basically this mode is entirely based on matching types.
In this mode, We don't need @Autowire annotation at the injection point as Spring doesn't search for places which are annotated with @Autowired.
In this mode of autowiring, the field injection doesn't work. There must be a setter. Spring scans all setters of a bean and if the type of property matches and there is no ambiguity then injects the target property.
In case of ambiguity (multiple beans available of same types), we have to use @Qualifier .
Examples
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class AutowireByType {
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
@Configuration
public static class Config {
@Bean(autowire = Autowire.BY_TYPE)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean1 () {
return new ServiceBean("Service bean 1");
}
}
private static class ClientBean {
private ServiceBean serviceBean;
public void setServiceBean (ServiceBean serviceBean) {
this.serviceBean = serviceBean;
}
public void doSomething () {
System.out.println(serviceBean.getMsg());
}
}
private static class ServiceBean {
private String msg;
public ServiceBean (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
} OutputService bean 1
Resolving ambiguity by using @Qualifier
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class AutowireByType2 {
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
@Configuration
public static class Config {
@Bean(autowire = Autowire.BY_TYPE)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean () {
return new ServiceBean("Service bean 1");
}
@Bean
public ServiceBean serviceBean2 () {
return new ServiceBean("Service bean 2");
}
}
private static class ClientBean {
private ServiceBean serviceBean;
public void setServiceBean (@Qualifier("serviceBean2") ServiceBean serviceBean) {
this.serviceBean = serviceBean;
}
public void doSomething () {
System.out.println(serviceBean.getMsg());
}
}
private static class ServiceBean {
private String msg;
public ServiceBean (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
} OutputService bean 2
Using @Qualifier at injection point and at bean definition
Following example uses @Qualifier at both places to resolve ambiguity.
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class AutowireByType3 {
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
@Configuration
public static class Config {
@Bean(autowire = Autowire.BY_TYPE)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean () {
return new ServiceBean("Service bean 1");
}
@Bean
@Qualifier("myService")
public ServiceBean serviceBean2 () {
return new ServiceBean("Service bean 2");
}
}
private static class ClientBean {
private ServiceBean serviceBean;
public void setServiceBean (@Qualifier("myService") ServiceBean serviceBean) {
this.serviceBean = serviceBean;
}
public void doSomething () {
System.out.println(serviceBean.getMsg());
}
}
private static class ServiceBean {
private String msg;
public ServiceBean (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
} OutputService bean 2
Example ProjectDependencies and Technologies Used: - spring-context 5.0.20.RELEASE (Spring Context)
Version Compatibility: 3.2.3.RELEASE - 5.3.31
- JDK 8
- Maven 3.8.1
|