Spring Beans Auto-wiring Example using XML Configuration

Bean wiring corresponds to providing the dependencies a bean might need to complete it’s job. In Spring, beans can be wired together in two ways : Manually and Autowiring.

Manual wiring : using ref attribute in <property> or <constructor> tag

In this approach, we use the ‘ref’ attribute to refer to exact bean we want to be wired. This is the cleanest approach, and easy to understand

	<!-- default example (autowire="no") -->
	<bean id="driver" class="com.websystique.spring.domain.Driver">
		<property name="license" ref="license"/>
	</bean>

	<bean id="license" class="com.websystique.spring.domain.License" >
		<property name="number" value="123456ABCD"/>
	</bean>

Autowiring : using autowire attribute in <bean> tag

	<bean id="application" class="com.websystique.spring.domain.Application" autowire="byName"/>

In this approach, beans can be automatically wired using Spring autowire feature. There are 4 supported options for autowiring.

  • autowire="byName" : Autowiring using property name. If a bean found with same name as the property of other bean, this bean will be wired into other beans property
  • autowire="byType" : If a bean found with same type as the type of property of other bean, this bean will be wired into other beans property
  • autowire="constructor" : If a bean found with same type as the constructor argument of other bean, this bean will be wired into other bean constructor
  • autowire="no" : No Autowiring. Same as explicitly specifying bean using ‘ref’ attribute

Let’s discuss each autowiring with an example:

1. autowire=”byName” example

Define Beans to work with

package com.websystique.spring.domain;

public class Application {

	private ApplicationUser applicationUser;

	public ApplicationUser getApplicationUser() {
		return applicationUser;
	}

	public void setApplicationUser(ApplicationUser applicationUser) {
		this.applicationUser = applicationUser;
	}

	@Override
	public String toString() {
		return "Application [applicationUser=" + applicationUser + "]";
	}
}
package com.websystique.spring.domain;

public class ApplicationUser {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "ApplicationUser [name=" + name + "]";
	}
}

Application needs ApplicationUser dependency, and have a property named applicationUser.

Spring Configuration XML file

<?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-4.0.xsd
        					http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- byName example -->
	<bean id="application" class="com.websystique.spring.domain.Application" autowire="byName"/>

	<bean id="applicationUser" class="com.websystique.spring.domain.ApplicationUser" >
		<property name="name" value="superUser"/>
	</bean>


</beans>

Notice that we have set the autowire="byName" attribute. We are nowhere referring to applicationUser bean explicitly. Since ‘application’ class have a property name ‘applicationUser’ which matches with the name of a bean defined in Spring context, that bean will be wired automatically.

Run Application
Load the context and run it.

package com.websystique.spring;

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

import com.websystique.spring.domain.Application;

public class AppMain {
	public static void main(String args[]){
		AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");

		//autowire=byName 
		Application application = (Application)context.getBean("application");
		System.out.println("Application Details : "+application);
	}
}

Following will be the output:

Application Details : Application [applicationUser=ApplicationUser [name=superUser]]

2. autowire=”byType” example

Define Beans to work with

package com.websystique.spring.domain;

public class Employee {

	private EmployeeAddress address;

	public EmployeeAddress getAddress() {
		return address;
	}

	public void setAddress(EmployeeAddress address) {
		this.address = address;
	}

	@Override
	public String toString() {
		return "Employee [address=" + address + "]";
	}
}
package com.websystique.spring.domain;

public class EmployeeAddress {

	private String Street;
	private String city;

	public String getStreet() {
		return Street;
	}

	public void setStreet(String street) {
		Street = street;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	@Override
	public String toString() {
		return "EmployeeAddress [Street=" + Street + ", city=" + city + "]";
	}
}

Employee needs EmployeeAddress type dependency.

Spring Configuration XML file

<?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-4.0.xsd
        					http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- byType example -->
	<bean id="employee" class="com.websystique.spring.domain.Employee" autowire="byType"/>

	<bean id="employeeAddress" class="com.websystique.spring.domain.EmployeeAddress" >
		<property name="street" value="112/223,SantaVila"/>
		<property name="city" value="Nebraska"/>
	</bean>

</beans>

Notice that we have set the autowire="byType" attribute. We are nowhere referring to employeeAddress bean explicitly from employee. Since ’employee’ class have a property of type ‘EmployeeAddress’ which matches with the type of a bean ’employeeAddress’ defined in Spring context, that bean will be wired automatically.

Run Application
Load the context and run it.

package com.websystique.spring;

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

import com.websystique.spring.domain.Employee;

public class AppMain {
	public static void main(String args[]){
		AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");

		//autowire=byType
		Employee employee = (Employee)context.getBean("employee");
	    System.out.println("Employee Details : "+employee);
	}
}

Following will be the output

Employee Details : Employee [address=EmployeeAddress [Street=112/223,SantaVila, city=Nebraska]]

3. autowire=”constructor” example

Define Beans to work with

package com.websystique.spring.domain;

public class Performer {
	
	private Instrument instrument;
	
	public Performer(Instrument instrument){
		this.instrument = instrument;
	}

	@Override
	public String toString() {
		return "Performer [instrument=" + instrument + "]";
	}
}
package com.websystique.spring.domain;

public class Instrument {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Instrument [name=" + name + "]";
	}
}

Notice that ‘Performer’ class has a constructor which accepts a ‘Instrument’ type argument.

Spring Configuration XML file

<?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-4.0.xsd
        					http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- constructor example -->
	<bean id="performer" class="com.websystique.spring.domain.Performer" autowire="constructor"/>

	<bean id="instrument" class="com.websystique.spring.domain.Instrument" >
		<property name="name" value="PIANO"/>
	</bean>

</beans>

Notice that we have set the autowire="constructor" attribute. We are nowhere referring to instrument bean explicitly from performer. Since ‘performer’ class have a constructor which accepts an argument of type ‘Instrument’ which matches with the type of a bean ‘instrument’ defined in Spring context, that bean will be wired automatically.

Run Application
Load the context and run it.

package com.websystique.spring;

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

import com.websystique.spring.domain.Performer;

public class AppMain {
	public static void main(String args[]){
		AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");

		//autowire=constructor
		Performer performer = (Performer)context.getBean("performer");
	    System.out.println("Performer Details : "+performer);
	}

}

Following will be the output

Performer Details : Performer [instrument=Instrument [name=PIANO]]

3. autowire=”no” example

Define Beans to work with

package com.websystique.spring.domain;

public class Driver {

	private License license;
	
	public void setLicense(License license) {
		this.license = license;
	}

	public License getLicense() {
		return license;
	}

	@Override
	public String toString() {
		return "Driver [license=" + license + "]";
	}
}

package com.websystique.spring.domain;

public class License {

	private String number;

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	@Override
	public String toString() {
		return "License [number=" + number + "]";
	}
	
}

Notice that Driver have a dependency on License.

Spring Configuration XML file

<?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-4.0.xsd
        					http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- default example (autowire="no") -->
	<bean id="driver" class="com.websystique.spring.domain.Driver" autowire="no">
		<property name="license" ref="license"/>
	</bean>

	<bean id="license" class="com.websystique.spring.domain.License" >
		<property name="number" value="123456ABCD"/>
	</bean>

</beans>

Notice that this time we have set autowire="no" attribute. This autowire attribute have no effect anymore on bean wiring , and can be removed altogether.There is no more auto-wiring here.

Also notice that we have set the ref atttibute to refer to a specific bean. If we don’t do that, driver’s license property will be null.

Run Application.
Load the context and run it.

package com.websystique.spring;

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

import com.websystique.spring.domain.Driver;

public class AppMain {
	public static void main(String args[]){
		AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");

		//autowire=default
	    Driver driver = (Driver)context.getBean("driver");
	    System.out.println("Driver Details : "+driver);

	
	}
}

Following will be the output

Driver Details : Driver [license=License [number=123456ABCD]]

That’s it. In the next post we will see Autowiring using Annotation based approach.

Download Source Code


References