Autowiring with @Autowired annotations
· autowiring can be done using @Autowired annotation.
· Here we can remove the attribute autowire=”byName / byType / Constructor” X
· We have to write only getter Method(), no need of setter methods
· To use @Autowired annotation in bean classes, you must enable the annotation by placing below code in spring.xml
<context:annotation-config
/>
(or)
<bean
class
="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
· @Autowired annotation can be used in 3 ways
1) @Autowired on Data members
2) @Autowired on setter method
3) @Autowired on constructor
1. @Autowired on Data members
· We have to place the annotation at top of the datamember
· We don’t need to write Setter method, if we use this
· It uses byType Auto wiring
Example
1. Employee.java
package bean;
import org.springframework.beans.factory.annotation.Autowired;
public class Employee {
private int id;
private String name;
@Autowired
private Dept dept;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dept getDept() {
return dept;
}
public void getData(){
System.out.println("===========================");
System.out.println(" Employee Details ");
System.out.println("===========================");
System.out.println("Emp. ID : "+getId());
System.out.println("Emp. Name : "+getName());
System.out.println("Department : "+getDept().getDname());
}
}
2. Dept.java
package bean;
public class Dept {
private String dname;
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
}
3. EmpMain.java
package bean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class EmpMain {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("res/spring.xml");
Employee emp = (Employee) context.getBean("emp");
emp.getData();
}
}
4. Spring.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.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- 1. Activate Annotations in XML -->
<context:annotation-config/>
<bean id="dept" class="bean.Dept">
<property name="dname" value="RELEASE MANAGEMENT"></property>
</bean>
<bean id="emp" class="bean.Employee">
<property name="id" value="5012"></property>
<property name="name" value="SATYA KAVETI"></property>
</bean>
</beans>
5. Output
===========================
Employee Details
===========================
Emp. ID : 5012
Emp. Name : SATYA KAVETI
Department : RELEASE MANAGEMENT
2) @Autowired on setter method
· We have to place the annotation at top of the setter method
· We need to write Setter method, if we use this
· It uses byType Auto wiring
Example: Dept.java, EmpMain.java, Spring.xml, Output is common for all
Employee.java
package bean;
import org.springframework.beans.factory.annotation.Autowired;
public class Employee {
private int id;
private String name;
private Dept dept;
@Autowired
public void setDept(Dept dept) {
this.dept = dept;
}
public Dept getDept() {
return dept;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void getData(){
System.out.println("===========================");
System.out.println(" Employee Details ");
System.out.println("===========================");
System.out.println("Emp. ID : "+getId());
System.out.println("Emp. Name : "+getName());
System.out.println("Department : "+getDept().getDname());
}
}
3) @Autowired on constructor
· We have to place the annotation at top of the constructor
· We need to write Setter method, we have to write parameterized constructor
· It uses constrcutor Auto wiring
Example
package bean;
import org.springframework.beans.factory.annotation.Autowired;
public class Employee {
private int id;
private String name;
private Dept dept;
@Autowired
public Employee(Dept dept) {
this.dept = dept;
}
public Dept getDept() {
return dept;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void getData(){
System.out.println("===========================");
System.out.println(" Employee Details ");
System.out.println("===========================");
System.out.println("Emp. ID : "+getId());
System.out.println("Emp. Name : "+getName());
System.out.println("Department : "+getDept().getDname());
}
}
Case (a): @Qualifier (“id”): if spring.xml contains 2 Dept. Objects? Then which Dept Object will Autowire
Spring.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.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- 1. Activate Annotations in XML -->
<context:annotation-config/>
<bean id="dept1" class="bean.Dept"> -------------(1)
<property name="dname" value="RELEASE MANAGEMENT"></property>
</bean>
<bean id="dept2" class="bean.Dept"> -------(2)
<property name="dname" value="DevOps Team"></property>
</bean>
<bean id="emp" class="bean.Employee">
<property name="id" value="5012"></property>
<property name="name" value="SATYA KAVETI"></property>
</bean>
</beans>
· (1) and (2) have same type of object, byType autowire will confuse which object to be autowire.
Error creating bean with name 'emp' defined in class path resource [res/spring.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type [bean.Dept]: : No qualifying bean of type [bean.Dept] is defined: expected single matching bean but found 2: dept1,dept2; nested exception isorg.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [bean.Dept] is defined: expected single matching bean but found 2: dept1,dept2
· In that case we have to put
@Qualifier("beanid")
to resolve conflict
· We can solve above error, below example code
Employee.java
package bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Employee {
private int id;
private String name;
private Dept dept;
@Autowired
@Qualifier("dept2")
public void setDept(Dept dept) {
this.dept = dept;
}
public Dept getDept() {
return dept;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void getData(){
System.out.println("===========================");
System.out.println(" Employee Details ");
System.out.println("===========================");
System.out.println("Emp. ID : "+getId());
System.out.println("Emp. Name : "+getName());
System.out.println("Department : "+getDept().getDname());
}
}
Output
===========================
Employee Details
===========================
Emp. ID : 5012
Emp. Name : SATYA KAVETI
Department : DevOps Team
Case (b): @Autowired(required=false): in spring.xml if we not define Dept property?
<context:annotation-config/>
<!-- <bean id="dept" class="bean.Dept">
<property name="dname" value="RELEASE MANAGEMENT"></property>
</bean> --> -----Ã Code Removed
<bean id="emp" class="bean.Employee">
<property name="id" value="5012"></property>
<property name="name" value="SATYA KAVETI"></property>
</bean>
</beans>
It will show the error
Error creating bean with name 'emp': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void bean.Employee.setDept(bean.Dept); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [bean.Dept] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
To Handle that error , we make Autowire is not Mandatory.see below code
package bean;
import org.springframework.beans.factory.annotation.Autowired;
public class Employee {
private int id;
private String name;
private Dept dept;
@Autowired(required=false)
public void setDept(Dept dept) {
this.dept = dept;
}
public Dept getDept() {
return dept;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void getData(){
System.out.println("===========================");
System.out.println(" Employee Details ");
System.out.println("===========================");
System.out.println("Emp. ID : "+getId());
System.out.println("Emp. Name : "+getName());
System.out.println("Department : "+getDept().getDname());
}
}
Output : it Just says NULL Ã No Error Now
===========================
Employee Details
===========================
Emp. ID : 5012
Emp. Name : SATYA KAVETI
Department : null
autowire-candidate
· Using ‘autowire-candidate‘as false totally exclude a bean from being an autowire candidate.
· It totally exclude that specific bean definition from being available to the auto wiring infrastructure.
<bean id="dept" class="bean.Dept" autowire-candidate="false">
<property name="dname" value="RELEASE MANAGEMENT"></property>
</bean>
default-autowire-candidates
· Autowire based on patterns of bean names.
· The top-level element accepts one or more patterns within its ‘default-autowire-candidates‘attribute. Autowire the beans whose name ends with ‘Bo’, provide a value of ‘*Bo’.
· To provide multiple patterns, define them in a comma-separated list.
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire-candidates="*Bo,*Dao"
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.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- 1. Activate Annotations in XML -->
<context:annotation-config/>
<bean id="dept" class="bean.DeptBo"">
<property name="dname" value="RELEASE MANAGEMENT"></property>
</bean>
<bean id="emp" class="bean.EmployeeBo">
<property name="id" value="5012"></property>
<property name="name" value="SATYA KAVETI"></property>
</bean>
</beans>