What is Autowiring in Spring?

Until now, we have discussed Dependencies Injection using the setter and constructor Injection. Now, In this article, we will discuss what is Autowiring and How it makes us do less configuration inside the config file.

What is Spring Bean Autowiring?

We declare all the bean dependencies in a config file, the container then creates an object by autowiring the relationship between collaborating beans. This is called Spring bean autowiring.

  • In this, we don’t need to use <construstor-arg> and <property> element in XML file.
  • Internally, It uses Setter Method or Constructor Injection.
  • It is used with reference type and not with primitive and String.

The Autowiring has the following Modes:

  • no mode
  • byName mode
  • byType mode
  • constructor mode

Let us discuss each mode one by one

no Mode

This is from the name itself we can understand i.e No Autowiring at all. This is the default mode.

byName mode

This mode injects the dependencies on the basis of the name of the bean. It is done in the following way

<bean id="bean" class="BeanName" autowire="byName">

Here, the autowire mode is set to byName. The container views the bean on which this mode is set and it matches its properties with the beans defined by the same name. If they are the same, It will inject those dependencies.

Let us take an example to understand byName mode.

In this example, we will create a Class Student where we will have a reference of Address Class with setter methods.

Create a Spring Project Go to File> New > Other > Search maven > Select Maven Project > Next > Search Filter org.apche.maven.archetypes/webapp > Next > Enter Group Id & Archetype id > Finish.

Address.java

package com.codedec.di;

public class Address {

  private String city;
  private String state;
  private String country;
  public void setCity(String city) {
    this.city = city;
  }
  public void setState(String state) {
    this.state = state;
  }
  public void setCountry(String country) {
    this.country = country;
  }
  @Override
  public String toString() {
    return "Address [city=" + city + ", state=" + state + ", country=" + country + "]";
  }
  
}

Student.java

package com.codedec.di;

public class Student {

  private String studentName;
  private Address address;
  
  
  public void setStudentName(String studentName) {
    this.studentName = studentName;
  }
  public void setAddress(Address address) {
    this.address = address;
  }
  public void show() {
    System.out.println("Student Name is "+studentName+ " \nStudent Address Info: "+address);
  }
}
  • Create a beans.xml file with autowire mode set to byName.
  • use the <property> element to set the values.
  • Here, we don’t need to use the ref attribute because spring will automatically auto-wire the referenced bean using byName mode.

beans.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">


  <bean id="s1" class="com.codedec.di.Student" autowire="byName">
    <property name="studentName" value="Nicolas"></property>
  </bean>
  <bean id="address" class="com.codedec.di.Address" >
  <property name="city" value="Bhusawal"></property>
  <property name="state" value="Maharashtra"></property>
  <property name="country" value="India"></property>
  </bean>

</beans>
  • Create an App.java and create the Object of Application Context, get the bean from it and call the show() method.

App.java

package com.codedec.di;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
     Student student= context.getBean("s1",Student.class);
     student.show();
  }
}

Output

Student Name is Nicolas 
Student Address Info: Address [city=Bhusawal, state=Maharashtra, country=India]

Thus, this is the way we use byName mode in XML Based configuration.

byType mode

This mode injects the dependencies on the basis of the type of the property of the bean. It is done in the following way

<bean id="bean" class="BeanName" autowire="byType">
  • Here, the autowire mode is set to byType.
  • The container views the properties of the bean on which this mode is set.
  • It matches its properties with exactly one of the beans defined by the same name.
  • If there is more than one such bean It will throw an exception. If they are the same, It will inject those dependencies.

Let us take an example to understand byType mode.

We will use the same example i.e we will create a Class Student where we will have a reference of Address Class with setter methods.

Create a Spring Project Go to File> New > Other > Search maven > Select Maven Project > Next > Search Filter org.apche.maven.archetypes/webapp > Next > Enter Group Id & Archetype id > Finish.

Address.java

package com.codedec.di;

public class Address {

  private String city;
  private String state;
  private String country;
  public void setCity(String city) {
    this.city = city;
  }
  public void setState(String state) {
    this.state = state;
  }
  public void setCountry(String country) {
    this.country = country;
  }
  @Override
  public String toString() {
    return "Address [city=" + city + ", state=" + state + ", country=" + country + "]";
  }
  
}

Student.java

package com.codedec.di;

public class Student {

  private String studentName;
  private Address address;
  public void setStudentName(String studentName) {
    this.studentName = studentName;
  }
  public void setAddress(Address address) {
    this.address = address;
  }
  public void show() {
    System.out.println("Student Name is "+studentName+ " \nStudent Address Info: "+address);
  }
}
  • Create a beans.xml file with autowire mode set to byType.
  • use the <property> element to set the values.
  • Here, we don’t need to use the ref attribute because spring will automatically auto-wire the referenced bean using byType mode.

beans.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">


  <bean id="s1" class="com.codedec.di.Student" autowire="byType">
    <property name="studentName" value="Nicolas"></property>
  </bean>
  <bean id="address" class="com.codedec.di.Address" >
  <property name="city" value="Bhusawal"></property>
  <property name="state" value="Maharashtra"></property>
  <property name="country" value="India"></property>
  </bean>

</beans>
  • Create an App.java and create the Object of Application Context, get the bean from it and call the show() method.

App.java

package com.codedec.di;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
     Student student= context.getBean("s1",Student.class);
     student.show();
  }
}

Output

Student Name is Nicolas 
Student Address Info: Address [city=Bhusawal, state=Maharashtra, country=India]

Thus, this is the way we use byType mode in XML Based configuration.

constructor mode

This is applied to <constructor-arg> element. It is similar to byType mode. It is done in the following way

<bean id="bean" class="BeanName" autowire="constructor">
  • Here, the autowire mode is set to the constructor.
  • The container views the class type of constructor argument of the bean on which this mode is set.
  • Then, It will do autowire byType on all constructor arguments.
  • If there is more than one such bean of constructor type argument It will throw an exception. If they are the same, It will inject those dependencies.

Let us take an example to understand constructor mode.

We will use the same example i.e we will create a Class Student where we will have a reference of Address Class with Constructor.

Create a Spring Project Go to File> New > Other > Search maven > Select Maven Project > Next > Search Filter org.apche.maven.archetypes/webapp > Next > Enter Group Id & Archetype id > Finish.

Address.java

package com.codedec.di;

public class Address {

  private String city;
  private String state;
  private String country;

  public Address(String city, String state, String country) {
    this.city = city;
    this.state = state;
    this.country = country;
  }
  @Override
  public String toString() {
    return "Address [city=" + city + ", state=" + state + ", country=" + country + "]";
  }
  
}

Student.java

package com.codedec.di;

public class Student {

  private String studentName;
  private Address address;
  
  public Student(String studentName, Address address) {
  
    this.studentName = studentName;
    this.address = address;
  }
  
  public void show() {
    System.out.println("Student Name is "+studentName+ " \nStudent Address Info: "+address);
  }
}
  • Create a beans.xml file with autowire mode set to the constructor.
  • use the <constructor-arg> element to set the values.
  • Here, we don’t need to use the ref attribute because spring will automatically auto-wire the referenced bean using constructor mode.

beans.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">


  <bean id="s1" class="com.codedec.di.Student" autowire="constructor">
    <constructor-arg name="studentName" value="Nicolas"></constructor-arg>
  </bean>
  <bean id="address" class="com.codedec.di.Address" >
  <constructor-arg name="city" value="Bhusawal"></constructor-arg>
  <constructor-arg name="state" value="Maharashtra"></constructor-arg>
  <constructor-arg name="country" value="India"></constructor-arg>
  </bean>

</beans>
  • Create an App.java and create the Object of Application Context, get the bean from it and call the show() method.

App.java

package com.codedec.di;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
     Student student= context.getBean("s1",Student.class);
     student.show();
  }
}

Output

Student Name is Nicolas 
Student Address Info: Address [city=Bhusawal, state=Maharashtra, country=India]

Thus, this is the way we use constructor mode in XML Based configuration. Here, the disadvantage is that it can’t be used with string and primitive values.

Hence, In this article, we have covered all the modes of Autowiring using XML Based Configuration. In the next article of this tutorial, we will see start with Annotation-based configuration.