Autowiring
Bean dependencies can be wired implicitly as well. This is known as Autowiring. There are few modes of wiring, enabling which will enable autowiring of bean dependencies.
Autowiring modes
1. No
No means autowiring is not enabled automatically. Dependencies need to be wired explicitly. We use ‘ref’ attribute of property element for explicit wiring as can be seen in the below xml.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="emp" class="com.sks.Employee">
<property name="id" value="10"></property>
<property name="name" value="Mark"></property>
<property name="age" value="25"></property>
<property name="add" ref="add1"></property>
</bean>
<bean id="add1" class="com.sks.Address">
<property name="addLine" value="101, street no 10"></property>
<property name="city" value="Sydney"></property>
<property name="country" value="Australia"></property>
<property name="pin" value="208128"></property>
</bean>
</beans>
2. byName
A dependency is autowired by its name in this mode. The only thing to remember is that the id of the injected bean should be exactly same as the name of the property in the java class. Let’s understand this with example
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="emp" class="com.sks.Employee" autowire="byName">
<property name="id" value="10"></property>
<property name="name" value="Mark"></property>
<property name="age" value="25"></property>
</bean>
<bean id="add" class="com.sks.Address">
<property name="addLine" value="101, street no 10"></property>
<property name="city" value="Sydney"></property>
<property name="country" value="Australia"></property>
<property name="pin" value="208128"></property>
</bean>
</beans>
pom.xml for this project
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sks</groupId>
<artifactId>autowiring-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.0</version>
</dependency>
</dependencies>
</project>
Employee.java
package com.sks;
public class Employee {
private int id;
private String name;
private int age;
private Address add;
//getters and setters
//constructors
//toString
}
Address.java
package com.sks;
public class Address {
private String addLine;
private String city;
private String country;
private int pin;
//getters and setters
//constructors
//toString
}
Testing.java
package com.sks;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Testing {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Employee e = (Employee)context.getBean("emp");
System.out.println(e);
((ClassPathXmlApplicationContext)context).close();
}
}
Output:
3. byType
In this mode, dependency is autowired by matching its type. It is checked if there is a type of a bean in the spring container or not. If yes, it will be autowired. In this mode, name of the bean is not matched with the name of the property in the java class.
Note -> In this mode, there should be exactly one bean of the type which is to be autowired, otherwise, there would be an ambiguity.
In the below xml, you can see that even though the id of the Address bean is not same as the name of the Address reference in the Employee class, it is still doing the autowiring. The reason is autowiring here is ‘byType’ which only checks the type of the dependency and not name.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="emp" class="com.sks.Employee" autowire="byType">
<property name="id" value="10"></property>
<property name="name" value="Mark"></property>
<property name="age" value="25"></property>
</bean>
<bean id="add1" class="com.sks.Address">
<property name="addLine" value="101, street no 10"></property>
<property name="city" value="Sydney"></property>
<property name="country" value="Australia"></property>
<property name="pin" value="208128"></property>
</bean>
</beans>
4. Constructor
In constructor autowiring mode, the dependency is injected via constructor with max number of parameters.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="emp" class="com.sks.Employee" autowire="constructor">
<constructor-arg name="id" value="10"></constructor-arg>
<constructor-arg name="name" value="Mark"></constructor-arg>
<constructor-arg name="age" value="25"></constructor-arg>
</bean>
<bean id="add1" class="com.sks.Address">
<constructor-arg name="addLine" value="101, street no 10"></constructor-arg>
<constructor-arg name="city" value="Sydney"></constructor-arg>
<constructor-arg name="country" value="Australia"></constructor-arg>
<constructor-arg name="pin" value="208128"></constructor-arg>
</bean>
</beans>