5.Spring – Aurowire
In previous Examples, for Dependency injection we wrote the bean properties explicitly into SpringConfig.xml file.
By using Autowiring we no need to write the bean properties explicitly into SpringConfig.xml, because Spring Container will take care about injecting the dependencies.
-
By default, autowiring is disabled in spring framework.
-
Autowiring supports only Object types, Not Primitive, Collection types
In Spring, 5 Auto-wiring modes are supported.
-
byName [ ID comparison]
-
byType [CLASS TYPE comparison]
-
Constructor
-
autoDetect
-
no
To activate Autowire in our application we need to configure autowire attribute
in
<bean id="id" class="class" autowire="byName/byType/constructor/autoDetect/no">
1.by Name
-
In this mode, spring framework will try to find out a bean in the SpringConfig.xml file, whose bean id **is matching with the **property name to be wired.
-
If a bean found with id as property name, then that class object will be injected into that property by calling setter injection
-
If no id is found then that property remains un-wired, but never throws any exception.
package core;
public class Student {
private int sno;
private String name;
private Address address;
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "Student [sno=" + sno + ", name=" + name + "]";
}
}
package core;
public class Address {
private int hno;
private String city;
public int getHno() {
return hno;
}
public void setHno(int hno) {
this.hno = hno;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address [hno=" + hno + ", city=" + city + "]";
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="st" class="core.Student" autowire="byName">
<property name="sno" value="100"></property>
<property name="name" value="Satya" />
<!-- This is Not Required
<property name="address">
<ref bean="address"/>
</property>
-->
</bean>
<bean id="address" class="core.Address">
<property name="hno" value="200"></property>
<property name="city" value="HYDERABAD"></property>
</bean>
</beans>
package core;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
// Instantiating a container
ApplicationContext context = new ClassPathXmlApplicationContext("SpDI.xml");
Student student = (Student) context.getBean("st");
System.out.println(student);
System.out.println(student.getAddress().toString());
}
}
Student [sno=100, name=Satya]
Address [hno=200, city=HYDERABAD]
In above example spring container compares the
2.byType
In ‘byType” mode, if data type of a bean in SpringConfig.xml is matched with data type of the Bean Property in bean class, it will autowire the properties using Setter Injection.
<beans>
<bean>
<bean id="student" class="core.Student" autowire="byType">
<property name="sno" value="101"></property>
<property name="name" value="Satya Kaveti"></property>
</bean>
<bean id="address" class="core.Address">
<property name="hno" value="322"></property>
<property name="city" value="HYDERABAD"></property>
</bean>
<bean id="address1" class="core.Address">
<property name="hno" value="322"></property>
<property name="city" value="HYDERABAD"></property>
</bean>
</beans>
In above you have multiple bean of same type, Container will confuse which bean should inject & throws NoSuchBeanDefinitionException:
by: *org.springframework.beans.factory.NoSuchBeanDefinitionException*: No unique
bean of type [core.Address] is defined: expected single matching bean but found
2: [address, address1]
To fix above problem, you need @Qualifier
to tell Spring about which bean
should autowired.
public class Student {
private int sno;
private String name;
@Qualifier("address")
private Address address;
}
3. Constructor
-
Autowiring by constructor is similar to byType, but here it will use Constructor for injection instead of Setter methods.
-
In this case we have to write the Constructor for Bean Property, but not Setter methods. That means we have write Constructor for address property instead of setAddress() method.
-
In there are multiple constructors like one-arg, two-arg, three-arg, it will take three-arg constructor for injecting properties. i.e. Max-arg Param constructor will do the job.
<?xml version="1.0" encoding="UTF-8"?>
<!-- File : SpringConfig.xml -->
<beans>
<bean id="student" class="constructor.Student" autowire="constructor">
<property name="sno" value="101"></property>
<property name="name" value="Satya Kaveti"></property>
</bean>
<bean id="address" class="constructor.Address">
<property name="hno" value="322"></property>
<property name="city" value="HYDERABAD"></property>
</bean>
</beans>
4.autodetect
-
autowire=”autodetect” first will works as constructor autowire if not, then works byType as Autowiring.
-
It is deprecated since Spring 3.
5.no
autowire=”no” is the default autowiring mode. It means no autowiring by default