Tired of changing your Java code and recompiling project when you want to change objects’ properties? The one possible solution is to create external file keeping all desired data and creating objects by hand. But… Wait a minute, doesn’t Java provide it already? The answer is: yes! Spring IoC (Inversion of Control) container is what you need. It this article I will show the simplest possible example of Spring IoC container using dependency injection technique. In this case: constructor injection (injecting properties with use of constructor) and setter injection (injecting properties with use of parameters’ setters).
Important: you must have following jars (or newer versions) in classpath:
commons-logging-1.1.1.jar org.springframework.asm-3.1.0.M1.jar org.springframework.beans-3.1.0.M1.jar org.springframework.context-3.1.0.M1.jar org.springframework.context.support-3.1.0.M1.jar org.springframework.core-3.1.0.M1.jar org.springframework.expression-3.1.0.M1.jar
You can download them in producents’ websites. Otherwise ClassNotFoundException will be thrown or project won’t compile.
Suppose you have following classes:
/** * Simple example class representing Bike: * has name and 2 wheels. */ class Bike { private String name; private Wheel frontWheel; private Wheel rearWheel; private String description; public Bike(String name) { this.name = name; } public Wheel getFrontWheel() { return frontWheel; } public void setFrontWheel(Wheel frontWheel) { this.frontWheel = frontWheel; } public Wheel getRearWheel() { return rearWheel; } public void setRearWheel(Wheel rearWheel) { this.rearWheel = rearWheel; } public String getName() { return name; } public void setDescription(String description) { this.description = description; } public String getDescription() { return description; } @Override public String toString() { return "NAME: " + getName() + "\nDESCRIPTION: " + getDescription() + "\nFRONTWHEEL: " + frontWheel + "\nREARWHEEL: " + rearWheel; } } /** * Bike's wheel. * Has name. */ class Wheel { private String name; public Wheel(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return "wheelname: " + getName(); } }
You want to defined their fields’ values in an external file. In Spring IoC container you can do it in an XML file (in this case spring/beans.xml in your main project catalogue):
So you have defined your objects. Let’s instantiate them in your project:
package spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringInversionOfControlTest { // You have to specify where // XML containing the rules of // dependency injection is. public static final String[] resources = new String[] { "spring/beans.xml" }; public static void main(String[] args) { // Set up application context by // providing array of XML resources. ApplicationContext applicationContext = new ClassPathXmlApplicationContext(resources); // And that's all! The only thing you have to do // to get instantiated in XMLs classes is to call // appropriate function from Spring IoC API. // In this case you get your object by class' object: Bike bike = applicationContext.getBean(Bike.class); // Let's see what you have: System.out.println(bike.toString()); } }
ApplicationContext provides various methods to access object defined in XML file (for example – by name or getting all object of provided type). I encourage you to get familiar with them.
The result of working program is:
NAME: codesmuggler's bike DESCRIPTION: This is my first bike. I use Spring IoC (Inversion of control) to instantiate it. Isn't Spring IoC great? FRONTWHEEL: wheelname: The name of front wheel REARWHEEL: wheelname: The name of rear wheel
As you see Spring IoC container provides simple and fluent API, which can be used in your projects. The article showed simple example of using it, but there are also more advanced options such as setting collections as properties.
Check also other curious articles about Spring IoC:
Spring IoC – autowiring, Configuring Spring IoC using @Annotations.
Pingback: [Java] Spring IoC Container – autowiring | CodeSmuggler
Hi codesmuggler,
thanks for the nice article. It is good to read and clear to understand. It was a good hint for me.
But one question is open for me. I searched up an down the internet for the answer, and now I hope you can provide it. Let´s take your example: I want to access the bean id (“MyBike”) within the class Bike or the id “FrontWheelId” / “RearWheelId” from class Wheel.
Is there a possibility to get (not set) the bean ID within the bean itself?
Thanks for a short answer,
Frank