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 propertyautowire="byType"
: If a bean found with same type as the type of property of other bean, this bean will be wired into other beans propertyautowire="constructor"
: If a bean found with same type as the constructor argument of other bean, this bean will be wired into other bean constructorautowire="no"
: No Autowiring. Same as explicitly specifying bean using ‘ref’ attribute Let’s discuss each autowiring with an 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]]
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]]
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]]
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.
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 improve further our learning process.
In this post we will be developing a full-blown CRUD application using Spring Boot, AngularJS, Spring Data, JPA/Hibernate and MySQL,…
Spring Boot complements Spring REST support by providing default dependencies/converters out of the box. Writing RESTful services in Spring Boot…
Being able to start the application as standalone jar is great, but sometimes it might not be possible to run…
Spring framework has taken the software development industry by storm. Dependency Injection, rock solid MVC framework, Transaction management, messaging support,…
Let's secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a…
This post shows how an AngularJS application can consume a REST API which is secured with Basic authentication using Spring…
View Comments
Very simple and to-the-point tutorial! I am a trainer and I will recommend this site to my students :)
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,
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)
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.