Spring @Autowired Annotation
March 13, 2023
This page will walk through Spring @Autowired
annotation example with setter methods, class field and constructor using XML and Java configuration.
1. In Spring framework, dependency injection of bean can be achieved automatically by using
@Autowired
annotation. We can use @Autowired
annotation on class fields, setter methods or constructor.
2. In this case, the required bean for dependency injection is searched by Spring container. If more than one bean is eligible for autowiring, the error will be thrown. We can avoid such situation by using
@Primary
annotation on one bean out of all eligible beans.
3. The
@Autowired
annotation looks for a bean to achieve dependency injection and if it does not find any suitable bean, it throws error. This is the default behavior of it. We can change this behavior by using @Autowired(required=false)
.
4. We can enable
@Autowired
annotation using JavaConfig as well as XML configuration . In JavaConfig, use @ComponentScan
annotation with @Configuration
. In XML configuration, configure AutowiredAnnotationBeanPostProcessor
class as bean.
5. If we are using
context:annotation-config
or context:component-scan
element in XML configuration that will also identify @Autowired
annotation.
Contents
With Setter Method using Java Configuration
The setter method of a property in a class can be annotated with@Autowired
. There can be more than one setter method annotated with @Autowired
. These methods should not be public. In our example we have two classes Employee
and Company
. These classes have been declared as Spring bean in java configuration. In the Employee
class we have setter method for Company
. To assign the value of Company
, @Autowired
annotation has been used.
Find the classes which has been created as bean. One of the bean is using
@Autowired
annotation.
Employee.java
package com.concretepage.bean; import org.springframework.beans.factory.annotation.Autowired; public class Employee { private Company company; public Company getCompany() { return company; } @Autowired void setCompany(Company company) { this.company = company; } }
package com.concretepage.bean; public class Company { private String compName; private String location; public String getCompName() { return compName; } public void setCompName(String compName) { this.compName = compName; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
@Configuration
.
AppConfig.java
package com.concretepage; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.concretepage.bean.Company; import com.concretepage.bean.Employee; @Configuration public class AppConfig { @Bean public Company getCompany() { Company company = new Company(); company.setCompName("ABCD Ltd"); company.setLocation("Varanasi"); return company; } @Bean public Employee getEmployee() { return new Employee(); } }
@Autowired
annotation application. Find the main class to run the example.
SpringDemo.java
package com.concretepage; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.concretepage.bean.Employee; public class SpringDemo { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); Employee employee = ctx.getBean(Employee.class); System.out.println("Company Name:"+ employee.getCompany().getCompName()); System.out.println("Location:"+ employee.getCompany().getLocation()); ctx.close(); } }
Company
has been injected in Employee
. Find the output.
Company Name:ABCD Ltd Location:Varanasi
With @ComponentScan Annotation
In Spring@ComponentScan
annotation scans a given package for the classes annotated with @Component
, @Service
, @Repository
and @Controller
. The classes with these annotations are behaved as bean. @Autowired
works well with these annotations. In our example we will annotate the classes with @Component
and Java configuration class will use @ComponentScan
to scan these classes.
Find the component.
Employee.java
package com.concretepage.bean; import org.springframework.stereotype.Component; @Component public class Employee { public String getEmpMsg() { return "Software makes world beautiful"; } }
package com.concretepage.bean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class EmployeeService { private Employee employee; public Employee getEmployee() { return employee; } @Autowired public void setEmployee(Employee employee) { this.employee = employee; } }
package com.concretepage; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages="com.concretepage.bean") public class AppConfig { }
package com.concretepage; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.concretepage.bean.EmployeeService; public class SpringDemo { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); EmployeeService service = ctx.getBean(EmployeeService.class); System.out.println(service.getEmployee().getEmpMsg()); ctx.close(); } }
Software makes world beautiful
Using required=false
By default the dependency injection for@Autowired
must be fulfilled because the value of required
attribute is true by default. We can change this behavior by using @Autowired(required=false)
. In this case if bean is not found for dependency injection, it will not through error.
EmployeeService.java
@Service public class EmployeeService { private Employee employee; public Employee getEmployee() { return employee; } @Autowired(required=false) public void setEmployee(Employee employee) { this.employee = employee; } }
With Constructor
Constructor arguments can also be autowired using@Autowired
. If there are more than one constructor in the class, only one constructor can have @Autowired
annotation. This constructor should not be public. Here the required
attribute of @Autowired
cannot be false. Find the example.
EmployeeService.java
package com.concretepage.bean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class EmployeeService { private Employee employee; @Autowired private EmployeeService(Employee employee) { this.employee = employee; } public Employee getEmployee() { return employee; } }
With Class Field
The class field can also be autowired using@Autowired
annotation. Any number of fields can be autowired within a class. The fields which are autowired should not be public. Find the example.
EmployeeService.java
package com.concretepage.bean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class EmployeeService { @Autowired private Employee employee; public Employee getEmployee() { return employee; } }
With @Qualifier Annotation
The@Qualifier
enforces the dependency injection for a specific bean name as given in @Qualifier
annotation.
Student.java
public class Student { @Autowired @Qualifier("add") private Address address; public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
address
will be autowired only with bean name add.
Find the URL for complete example of @Qualifier
with @Autowired
.
Using AutowiredAnnotationBeanPostProcessor in XML
TheAutowiredAnnotationBeanPostProcessor
process the @Autowired
annotation marked on setter method, fields and constructor. We need to create a bean for AutowiredAnnotationBeanPostProcessor
in our application context XML.
app-conf.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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> <bean class="com.concretepage.bean.Address"> <property name="city" value="Varanasi"/> <property name="state" value="Uttar Pradesh"/> </bean> <bean class="com.concretepage.bean.Employee"/> </beans>
package com.concretepage.bean; public class Address { private String city; private String state; public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } }
package com.concretepage.bean; import org.springframework.beans.factory.annotation.Autowired; public class Employee { @Autowired private Address address; public Address getAddress() { return address; } }
package com.concretepage; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.concretepage.bean.Employee; public class SpringDemo { public static void main(String[] args){ AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("app-conf.xml"); Employee emp = ctx.getBean(Employee.class); System.out.println(emp.getAddress().getCity()); System.out.println(emp.getAddress().getState()); ctx.registerShutdownHook(); } }
Varanasi Uttar Pradesh
Using context:annotation-config in XML
If XML is usingcontext:annotation-config
, we need not to create bean for AutowiredAnnotationBeanPostProcessor
. The context:annotation-config
will enable the processing of @Autowired
.
app-conf.xml
<context:annotation-config/> <bean class="com.concretepage.bean.Address"> <property name="city" value="Varanasi"/> <property name="state" value="Uttar Pradesh"/> </bean> <bean class="com.concretepage.bean.Employee"/>
Using context:component-scan in XML
Thecontext:component-scan
also enables @Autowired
annotation. Our classes annotated with @Component
are scanned by context:component-scan
.
app-conf.xml
<context:component-scan base-package="com.concretepage.bean"/> <bean class="com.concretepage.bean.Address"> <property name="city" value="Varanasi"/> <property name="state" value="Uttar Pradesh"/> </bean>
@Component public class Employee { @Autowired private Address address; public Address getAddress() { return address; } }