This article shows Spring Dependency Injection Annotation example + Spring Auto-wiring Annotation example.
We will learn Spring Dependency Injection and Beans auto-wiring using Spring @Autowired
annotation. @Autowired can be applied on a bean’s constructor, field, setter method or a config method to autowire the dependency using Spring’s dependency injection.
@Autowired wires the dependency using bean datatype
. If you are looking for bean wiring using bean name (somewhat analogues to byName in XML), you can use standard @Resource
annotation with ‘name’ attribute. @Qualifier
annotation is often used in conjunction with @Autowired to resolve ambiguity in case more that one bean of injected type exist in application context. Let’s get going.
Let’s explore practical usage of each of them in detail via examples:
Define Beans to work with
package com.websystique.spring.domain; import javax.annotation.Resource; import org.springframework.stereotype.Component; @Component("application") public class Application { @Resource(name="applicationUser") private ApplicationUser user; @Override public String toString() { return "Application [user=" + user + "]"; } }
package com.websystique.spring.domain; import org.springframework.stereotype.Component; @Component("applicationUser") public class ApplicationUser { private String name = "defaultName"; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "ApplicationUser [name=" + name + "]"; } }
Standard @Resource
annotation marks a resource that is needed by the application. It is analogous to @Autowired in that both injects beans by type when no attribute provided. But with name attribute, @Resource allows you to inject a bean by it’s name, which @Autowired does not.
In above code, Application’s user property is annotated with @Resource(name=”applicationUser”). In this case, a bean with name ‘applicationUser’ found in applicationContext will be injected here.
Spring Configuration Class
package com.websystique.spring.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.websystique.spring") public class AppConfig { }
Notice @ComponentScan
which will make Spring auto detect the annotated beans via scanning the specified package and wire them wherever needed (using @Resource or @Autowired ).
Above configuration is analogues to following in XML
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="com.websystique.spring" /> </beans>
Run Application
Load the context and run it.
package com.websystique.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import com.websystique.spring.config.AppConfig; import com.websystique.spring.domain.Application; public class AppMain { public static void main(String args[]){ AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); //Byname Autowiring Application application = (Application)context.getBean("application"); System.out.println("Application Details : "+application); } }
Following will be the output.
Application Details : Application [user=ApplicationUser [name=defaultName]]
Define Beans to work with
package com.websystique.spring.domain; import org.springframework.stereotype.Component; @Component public class License { private String number="123456ABC"; @Override public String toString() { return "License [number=" + number + "]"; } //setters, getters }
@Autowired on Setter method
package com.websystique.spring.domain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component("driver") public class Driver { private License license; @Autowired public void setLicense(License license) { this.license = license; } @Override public String toString() { return "Driver [license=" + license + "]"; } //getter }
@Autowired on Field
package com.websystique.spring.domain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component("driver") public class Driver { @Autowired private License license; //getter,setter @Override public String toString() { return "Driver [license=" + license + "]"; } }
@Autowired on Constructor
package com.websystique.spring.domain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component("driver") public class Driver { private License license; @Autowired public Driver(License license){ this.license = license; } @Override public String toString() { return "Driver [license=" + license + "]"; } }
Run Application
Load the context and Run it.
package com.websystique.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import com.websystique.spring.config.AppConfig; import com.websystique.spring.domain.Driver; public class AppMain { public static void main(String args[]) { AbstractApplicationContext context = new AnnotationConfigApplicationContext( AppConfig.class); Driver driver = (Driver) context.getBean("driver"); System.out.println("Driver Details : " + driver); } }
Following will be the output
Driver Details : Driver [license=License [number=123456ABC]]
@Qualifier
is useful for the situation where you have more than one bean matching the type of dependency and thus resulting in ambiguity.
Define Beans to work with
package com.websystique.spring.domain; public interface Car { public void getCarName(); }
package com.websystique.spring.domain; import org.springframework.stereotype.Component; @Component("Ferari") public class Ferari implements Car{ public void getCarName() { System.out.println("This is Ferari"); } }
package com.websystique.spring.domain; import org.springframework.stereotype.Component; @Component("Mustang") public class Mustang implements Car{ public void getCarName() { System.out.println("This is Mustang"); } }
package com.websystique.spring.domain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component public class Bond { @Autowired private Car car; public void showCar(){ car.getCarName(); } }
Run Applicaion
Load context and Run it.
package com.websystique.spring; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import com.websystique.spring.config.AppConfig; import com.websystique.spring.domain.Bond; public class AppMain { public static void main(String args[]) { AbstractApplicationContext context = new AnnotationConfigApplicationContext( AppConfig.class); Bond bond = (Bond) context.getBean("bond"); bond.showCar(); } }
On running, Spring throws following exception:
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.websystique.spring.domain.Car] is defined: expected single matching bean but found 2: Ferari,Mustang at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:970) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480) ... 14 more
What happened is Spring was not able to decide which bean (Ferari or Mustang as both implements Car) to choose for auto-wiring ,it throws this exception.
Happily, @Qualifier saves the day.
Change the Bond class as shown below
package com.websystique.spring.domain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component public class Bond { @Autowired @Qualifier("Mustang") private Car car; public void showCar(){ car.getCarName(); } }
Run Application
Following will be the output.
This is Mustang
By default, @Autowored annotation makes sure that field is indeed autowired. In case autowiring is not successful, Spring will throw an exception. There are times however when you want to make autowiring optional. Setting @Autowired required attribute to ‘false’ will make this filed optional for autowiring and Spring will skip it(remain null) if dependency not found.
package com.websystique.spring.domain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component("driver") public class Driver { @Autowired(required=false) private License license; //getter,setter @Override public String toString() { return "Driver [license=" + license + "]"; } }
In above example, if no bean of type License been found, it will remain null and no error will be thrown on context loading.
caveat :
Note that standard @Resource annotation does not have this flexibility. In case the dependency annotated with @Resource not found, Spring will throw an exception. Both @Resource and @Autowired have few differences : No optionality in @Resource and no autowiring by bean name in @Autowired.
All in all, @Autowired is the most widely used option compare to @Resource and autowire attribute in XML.
That’s it.
References
If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help improve further our learning process.
In this post we will be developing a full-blown CRUD application using Spring Boot, AngularJS, Spring Data, JPA/Hibernate and MySQL,…
Spring Boot complements Spring REST support by providing default dependencies/converters out of the box. Writing RESTful services in Spring Boot…
Being able to start the application as standalone jar is great, but sometimes it might not be possible to run…
Spring framework has taken the software development industry by storm. Dependency Injection, rock solid MVC framework, Transaction management, messaging support,…
Let's secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a…
This post shows how an AngularJS application can consume a REST API which is secured with Basic authentication using Spring…
View Comments
Finally found good tutorial, explained how injection works and differences between annotations in plain english.
Well explained..!!
Another fantastic article.
Thank you a lot.