Using @Autowired at field.
public class OrderServiceClient {
@Autowired
@Qualifier("OrderServiceA")
private OrderService orderService;
public void showPendingOrderDetails () {
for (String orderId : Arrays.asList("100", "200", "300")) {
System.out.println(orderService.getOrderDetails(orderId));
}
}
}
Original PostThis example demonstrates how @Autowired annotation is used to throw NoSuchBeanDefinitionException. By default @Autowired(required=true) which means the annotated injection point must be set with the dependency.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Configuration
@ComponentScan(useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "SetterAutowiredExample"))
public class SetterAutowiredExample {
public static void main(String... strings) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
SetterAutowiredExample.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
@Component
public static class ClientBean {
private ServiceBean serviceBean;
@Autowired
public void setServiceBean(ServiceBean serviceBean) {
this.serviceBean = serviceBean;
}
public void doSomething() {
System.out.println("doing something with : " + serviceBean);
}
}
//uncomment following to get rid of UnsatisfiedDependencyException
//@Service
public static class ServiceBean {
}
}
Original PostUsing Autowire.NO
mode. This example shows that in Autowire.NO mode too (in fact, in all autowiring modes), Spring framework first tries to match by name. If there's no match by 'name' then it falls back to matching by type approach. Try to change autowire = Autowire.NO to autowire = Autowire.BY_TYPE on clientBean()
method, we will still have a successful match by 'name'.
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;
}
}
}
Output
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'clientBean': Unsatisfied dependency expressed through field 'serviceBean'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.logicbig.example.AutowireNoExample2$ServiceBean' available: expected single matching bean but found 2: serviceBean1,serviceBean2
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue (AutowiredAnnotationBeanPostProcessor.java:660)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor.java:640)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject (InjectionMetadata.java:119)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties (AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean (AbstractAutowireCapableBeanFactory.java:1413)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:601)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0 (AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:944)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:918)
at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:583)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init> (AnnotationConfigApplicationContext.java:93)
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' available: expected single matching bean but found 2: serviceBean1,serviceBean2
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique (DependencyDescriptor.java:220)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency (DefaultListableBeanFactory.java:1358)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency (DefaultListableBeanFactory.java:1300)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue (AutowiredAnnotationBeanPostProcessor.java:657)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor.java:640)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject (InjectionMetadata.java:119)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties (AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean (AbstractAutowireCapableBeanFactory.java:1413)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:601)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0 (AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:944)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:918)
at org.springframework.context.support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:583)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init> (AnnotationConfigApplicationContext.java:93)
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)
Original PostUsing autowiring mode Autowire.BY_TYPE
. We don't need to use @Autowired. There should be only one injection point matching the same type otherwise we will have NoUniqueBeanDefinitionException
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;
}
}
}
Output
Service bean 1
Original PostUsing autowiring mode Autowire.BY_NAME
. We need to use @Autowired at the injection point.
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 AutowireByName {
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_NAME)
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 serviceBean1;
public void doSomething () {
System.out.println(serviceBean1.getMsg());
}
}
private static class ServiceBean {
private String msg;
public ServiceBean (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
}
Output
Service bean 1
Original PostUsing autowiring mode Autowire.BY_NAME
.
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;
/**
* In this example we are explicitly giving the bean a name by using @Bean(name =....)
*/
public class AutowireByName2 {
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_NAME)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean(name = "someOtherServiceBean")
public ServiceBean serviceBean1 () {
return new ServiceBean("Service bean 1");
}
@Bean
public ServiceBean serviceBean2 () {
return new ServiceBean("Service bean 2");
}
}
private static class ClientBean {
private ServiceBean someOtherServiceBean;
@Autowired
public void setSomeOtherServiceBean (ServiceBean serviceBean) {
this.someOtherServiceBean = serviceBean;
}
public void doSomething () {
System.out.println(someOtherServiceBean.getMsg());
}
}
private static class ServiceBean {
private String msg;
public ServiceBean (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
}
Output
Service bean 1
Original PostUsing Autowire.NO
mode. This example shows that in Autowire.NO mode too (in fact, in all autowiring modes), Spring framework first tries to match by name. If there's no match by 'name' then it falls back to matching by type approach. Try to change autowire = Autowire.NO to autowire = Autowire.BY_TYPE on clientBean()
method, we will still have a successful match by 'name'.
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;
}
}
}
Output
Service Bean 2
Original PostUsing autowiring mode Autowire.BY_TYPE
and @Qualifier
.
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;
}
}
}
Original PostUsing autowiring mode Autowire.BY_TYPE
and @Qualifier
(at bean declaration and injection point).
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;
}
}
}
Original PostUsing autowiring mode Autowire.BY_NAME
.
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;
import org.springframework.context.annotation.Configuration;
/**
* In this example we are explicitly giving the bean a name by using @Bean(name =....)
*/
public class AutowireByName3 {
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_NAME)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean1 () {
return new ServiceBean("Service bean 1");
}
@Bean(name = "myService")
public ServiceBean serviceBean2 () {
return new ServiceBean("Service bean 2");
}
}
private static class ClientBean {
private ServiceBean serviceBean;
@Autowired
@Qualifier("myService")
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;
}
}
}
Output
Service bean 2
Original PostUsing autowiring mode Autowire.BY_NAME
.
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;
import org.springframework.context.annotation.Configuration;
/**
* In this example we are explicitly giving the bean a name by using @Bean(name =....)
*/
public class AutowireByName4 {
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_NAME)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean1 () {
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;
@Autowired
@Qualifier("myService")
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;
}
}
}
Output
Service bean 2
Original Post@Autowired can be used on any arbitrary method, even with multiple parameters:
import org.springframework.beans.factory.annotation.Autowired;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Greeter {
private String greetingFormat;
@Autowired
public void configure(GreetingService greetingService, LocalDateTime appServiceTime) {
greetingFormat = String.format("%s. This app is running since: %s%n", greetingService.getGreeting("<NAME>"),
appServiceTime.format(DateTimeFormatter.ofPattern("YYYY-MMM-d")));
}
public void showGreeting(String name) {
System.out.printf(greetingFormat.replaceAll("<NAME>", name));
}
}
Original Post