This is the default. We have to explicitly use @Autowire annotation at injection point. That means Spring doesn't do automatic wiring in this mode. We have to tell Spring that at what points bean wiring should happen by specifying @Autowired annotation at those points.
On finding @Autowired annotation, Spring attempts to match injection point type with the available registered beans type for a successful injection.
Bean ambiguity
There shouldn't be any conflict (ambiguity), which means there should be no more than one bean instance of the same type registered for a given injection point, otherwise we will have NoUniqueBeanDefinitionException .
Example
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class AutowireNoExample {
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.NO)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean () {
return new ServiceBean("Service bean 1");
}
}
private static class ClientBean {
@Autowired
private 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
If there are two beans available of the required type then the match is performed based on the bean's name. If no match is found then NoUniqueBeanDefinitionException is thrown.
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
public class AutowireNoExample2 {
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
public static class Config {
@Bean(autowire = Autowire.NO)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean1 () {
return new ServiceBean("Service Bean 1");
}
@Bean
public ServiceBean serviceBean2 () {
return new ServiceBean("Service Bean 2");
}
}
private static class ClientBean {
@Autowired
private 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;
}
}
} Outputorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientBean': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.logicbig.example.AutowireNoExample2$ServiceBean com.logicbig.example.AutowireNoExample2$ClientBean.serviceBean; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.logicbig.example.AutowireNoExample2$ServiceBean] is defined: expected single matching bean but found 2: serviceBean2,serviceBean1 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues (AutowiredAnnotationBeanPostProcessor.java:334) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean (AbstractAutowireCapableBeanFactory.java:1214) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:543) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:482) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject (AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:772) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:838) at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:537) at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init> (AnnotationConfigApplicationContext.java:84) at com.logicbig.example.AutowireNoExample2.main (AutowireNoExample2.java:20) at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke (Method.java:498) at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:282) at java.lang.Thread.run (Thread.java:748) Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.logicbig.example.AutowireNoExample2$ServiceBean com.logicbig.example.AutowireNoExample2$ClientBean.serviceBean; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.logicbig.example.AutowireNoExample2$ServiceBean] is defined: expected single matching bean but found 2: serviceBean2,serviceBean1 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor.java:573) at org.springframework.beans.factory.annotation.InjectionMetadata.inject (InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues (AutowiredAnnotationBeanPostProcessor.java:331) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean (AbstractAutowireCapableBeanFactory.java:1214) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:543) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:482) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject (AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:772) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:838) at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:537) at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init> (AnnotationConfigApplicationContext.java:84) at com.logicbig.example.AutowireNoExample2.main (AutowireNoExample2.java:20) at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke (Method.java:498) at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:282) at java.lang.Thread.run (Thread.java:748) Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.logicbig.example.AutowireNoExample2$ServiceBean] is defined: expected single matching bean but found 2: serviceBean2,serviceBean1 at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency (DefaultListableBeanFactory.java:1126) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency (DefaultListableBeanFactory.java:1014) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor.java:545) at org.springframework.beans.factory.annotation.InjectionMetadata.inject (InjectionMetadata.java:88) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues (AutowiredAnnotationBeanPostProcessor.java:331) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean (AbstractAutowireCapableBeanFactory.java:1214) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:543) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:482) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject (AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:772) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:838) at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:537) at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init> (AnnotationConfigApplicationContext.java:84) at com.logicbig.example.AutowireNoExample2.main (AutowireNoExample2.java:20) at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke (Method.java:498) at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:282) at java.lang.Thread.run (Thread.java:748)
To fix above exception either use bean default name or @Qualifier at the injection point.
Using bean default name
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
public class AutowireNoExample3 {
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
public static class Config {
@Bean(autowire = Autowire.NO)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean1 () {
return new ServiceBean("Service Bean 1");
}
@Bean
public ServiceBean serviceBean2 () {
return new ServiceBean("Service Bean 2");
}
}
private static class ClientBean {
@Autowired
private ServiceBean serviceBean2;
public void doSomething () {
System.out.println(serviceBean2.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 annotation
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
public class AutowireNoExample4 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
public static class Config {
@Bean(autowire = Autowire.NO)
public ClientBean clientBean() {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean1() {
return new ServiceBean("Service Bean 1");
}
@Bean
public ServiceBean serviceBean2() {
return new ServiceBean("Service Bean 2");
}
}
private static class ClientBean {
@Autowired
@Qualifier("serviceBean2")
private 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 4.2.3.RELEASE: Spring Context.
- JDK 1.8
- Maven 3.6.3
|