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

If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help me improve further our learning process.

If you appreciate the effort I have put in this learning site, help me improve the visibility of this site towards global audience by sharing and linking this site from within and beyond your network. You & your friends can always link my site from your site on www.websystique.com, and share the learning.

After all, we are here to learn together, aren’t we?

  • Navin Israni

    Very simple and to-the-point tutorial! I am a trainer and I will recommend this site to my students :)

  • Pingback: Spring bean依赖注入、bean的装配及相关注解 - 风一样的码农 - – 引力一族()

  • John Nexus

    Hi,
    I appreciate your efforts for the great tutorial. I could not understand the primary and clear-cut difference between “byType” and “byName” auto-wiring. It would be helpful if you just explain it explicitly, for now they both just look same with different examples.

    Thanks,

    • Navin Israni

      byName – looks for beans with “id” property same as “dependency” identifier. So, if in the Student-Address example above, you chose “byName”, and you named the address reference in Student object as “addr”, then in order to get Spring to do this correctly – Spring will search for a bean with (id=”addr”) and you would need to create a bean with (id=”addr”) of type “Address”. If you have a bean with (id=”addr”) but it is of another type than Address, then Spring cannot inject and will throw a ClassCastException (or similar)

      • Navin Israni

        in “byType”, the name of dependency object in the container object can be different from the bean id. Spring will search according to the type. This also means that Spring will accept only one bean with one type. If it gets two different beans of same type, and the container object specifies “byType” autowiring, then Spring will get confused about which bean to inject into the container object – because with “myType” it assumes only one dependency bean of each dependency type across your WHOLE IOC container.