IOC and Dependency Injection

Topics Covered:

  • What is Inversion of Control and Dependency Injection?
  • Lets write our own simple IOC container form scratch using Java and XML.
  • What are some of the practical uses of IOC and DI?
Figure 1: IOC and Dependency Injection

Figure 1: IOC and Dependency Injection

In figure 1 we have an arbitrary object called “AnObject” (item 1 in the image) and an arbitrary XML configuration defining our object attributes (item 2 in the image).  Inversion of Control describes an object creation flow/process in which objects are created and their attributes set or loaded dynamically at run-time via an IOC container. This is achieved using Dependency Injection (a design pattern).

There are three types of Dependency Injection:

  • Interface injection: Is used when an object is defined by an interface that it must implemented in order to inject dependencies at runtime.
  • Setter injection: Is used to refer to an object exposing a setter method(s) to inject dependencies at run-time.
  • Constructor injection: Generally the same concept as setter injection except we utilize the constructor instead (this is what we use in our example below).

The example below has been written using all three techniques (setter, constructor, and interface) so you can get a better idea of the differences.  The displayed and discussed code is the one which uses Constructor Injection, but all three versions are available for download at the end of the article.

For our example we will use Dependency Injection to inject object attributes defined in an XML configuration file (IOC-application-context.xml).

DEVHUB Example IOC Container using Java and XML

Figure 2: DEVHUB Example IOC Container using Java and XML

Figure 2 above contains the components of our simple IOC Container application. We have the container itself (DevHubContainer.java), our objects Band.java and BandMember.java, and the configuration file defining our object dependencies and attributes (IOC-application-context.xml).

IOC-application-context.xml

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<beans>
    <bean id="Robert" class="fm.devhub.objects.BandMember">
        <property name="name" value="Robert Plant" />
    </bean>
    <bean id="Jimmy" class="fm.devhub.objects.BandMember">
        <property name="name" value="Jimmy Page" />
    </bean>
    <bean id="John" class="fm.devhub.objects.BandMember">
        <property name="name" value="John Bonham" />
    </bean>
    <bean id="Jones" class="fm.devhub.objects.BandMember">
        <property name="name" value="John Paul Jones" />
    </bean>
    <bean id="Band" class="fm.devhub.objects.Band">
        <property name="name" value="Led Zeppelin" />
        <property name="label" value="Atlantic" />
        <property name="genere" value="Rock" />
        <property name="singer" bean-reference="Robert" ref-class="fm.devhub.objects.BandMember"/>
        <property name="bass" bean-reference="Jones" ref-class="fm.devhub.objects.BandMember" />
        <property name="guitarist" bean-reference="Jimmy" ref-class="fm.devhub.objects.BandMember"/>
        <property name="drummer" bean-reference="John" ref-class="fm.devhub.objects.BandMember"/>
    </bean>    
</beans>

Lines 2-13:
Here we define our simple Objects, we have members of a musical band belonging to the package fm.devhub.objects.BandMember, and one attribute defined which is the name of the band member.

Lines 14-22:
We define our band Object. Its basically is composed of some attributes defining the name of the band etc. But also notice it defines some Object references, band-members. So when we construct our Band object, the IOC Container will know to include Objecs of type BandMember as well.

BandMember.java

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package fm.devhub.objects;
import java.util.ArrayList;
/*
* This class resembles a Band Member Bean or POJO.
* Properties for our Band Member are injected using
* our IOC Container & Constructor Injection.
*/
public class BandMember {
    private String name;
    
    public BandMember(){
    }
    
    public BandMember ( ArrayList<String> name ){
        
        this.name = (String) name.get(0);
    }
    public String toString() {
        return "Member Name: " + name;
    }
}

Here we have a simple Object called BandMember, it has one attribute which defines the name of the band member. Because this example is using Constructor Injection, I didnt include any set or get methods. The object is constructed by our IOC container which injects the constructor value at runtime based on what is defined in IOC-application-context.xml.

Band.java

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package fm.devhub.objects;
import java.util.ArrayList;
/*
* This class resembles a Band Bean or POJO.
* Properties for our Band Member are injected using
* our IOC Containe and Constructor
* Injection.
*/
public class Band {
    private String name;
    private String label;
    private String genere;
    private BandMember singer;
    private BandMember bass;
    private BandMember guitarist;
    private BandMember drummer;
    public Band() {
    }
    public Band( ArrayList<Object> params ) {
        this.name = params.get(0).toString();
        this.label = params.get(1).toString();
        this.genere = params.get(2).toString();
        this.singer = (BandMember) params.get(3);
        this.bass = (BandMember) params.get(4);
        this.guitarist = (BandMember) params.get(5);
        this.drummer = (BandMember) params.get(6);
    }
    public String toString() {
        return "Name: " + name + "\nLabel: " + label + "\nGenre: " + genere + "\nSinger " + singer
                + "\nBass " + bass + "\nGuitarist " + guitarist + "\nDrummer "
                + drummer;
    }
}

Band is very similar to BandMember. The only difference is that there are more attributes being set. Once again our IOC Container will inject those values at runtime based on the relationships defined in IOC-application-context.xml.

DevHubContainer.java

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package fm.devhub.ioccontainer;
//Import the Java classes
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
//Import the Reflection classes
import java.lang.reflect.Constructor;
//Import the JDOM classes
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
/*
* This is our simple IOC Container, it parses
* IOC-application-context.xml and uses DI
* to create and assemble the beans.
*/
public class DevHubContainer {
    /**
  * Keeps track of all our bean nodes.
  */
    private List<Object> beanList;
    
    /**
  * Creates a new DevHubContainer that is configured by the specified XML
  * filename, we use JDOM SAX to traverse through our XML document.
  */
    public DevHubContainer(String application_context) {
        try {
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(application_context);
            Element root = doc.getRootElement();
            this.beanList = root.getChildren("bean");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
  * Returns a configured bean based on the name for example: <bean id="Band"
  * class="fm.devhub.objects.Band"> has the name 'Band'
  */
    public Object getBean(String name) {
        // Iterate over our bean list, this was
        // populated during the instantiation of our
        // IOC container.
        for (Iterator i = this.beanList.iterator(); i.hasNext();) {
            Element bean = (Element) i.next();
            String id = bean.getAttributeValue("id");
            if (id.equals(name)) {
                try {
                    String className = bean.getAttributeValue("class");
                    List propertyList = bean.getChildren("property");
                    ArrayList elementValue = new ArrayList();
                    if (propertyList.size() > 0) {
                        for (Iterator it = propertyList.iterator(); it.hasNext();) {
                            Element propertyElement = (Element) it.next();
                            String propertyValue = propertyElement
                                    .getAttributeValue("value");
                            String propertyReference = null;
                            if (propertyValue == null) {
                                propertyReference = propertyElement.getAttributeValue("bean-reference");
                                Class refbeanClass = Class.forName( propertyElement.getAttributeValue("ref-class") );                                
                                Constructor[] refconstruct = refbeanClass.getConstructors();
                                ArrayList<String> propertyReferenceValue = new ArrayList();
                                propertyReferenceValue.add( propertyReference );
                                Object refbeanInstance = refconstruct[1].newInstance(propertyReferenceValue);
                                elementValue.add(refbeanInstance);
                            } else {
                                elementValue.add(propertyValue);
                            }
                        }
                    }
                    Class beanClass = Class.forName(className);
                    Constructor[] construct = beanClass.getConstructors();
                    Object beanInstance = construct[1].newInstance(elementValue);
                    return beanInstance;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        // If no matching objects are found, then return null
        return null;
    }
}

Lines 35-44:
We build a parser using JDOM and pass it our IOC-application-context xml.

Lines 60-90:
Here is the core of our IOC Container, we iterate over our application context, and create the objects defined. The objects are created very simply as follows:

     Class beanClass = Class.forName(className);
     Constructor[] construct = beanClass.getConstructors();
     Object beanInstance = construct[1].newInstance(elementValue);

elementValue is an ArrayList containing all of the values that need to be set in the objects constructor.

IOCContainerTest.java

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package fm.devhub.test;
import fm.devhub.ioccontainer.DevHubContainer;
import fm.devhub.objects.Band;
import fm.devhub.objects.BandMember;
public class IOCContainerTest {
    public static void main( String[] args ) {
       /*
       * We instantiate our IOC Container, and load our application-context
       * Then we use IOCContainer.getBean() to inject our Band and BandMember bean
       * configuration attributes.
       */
       DevHubContainer IOCContainer = new DevHubContainer( "C:\\IOC-application-context.xml" );
        
       BandMember Jimmy = ( BandMember )IOCContainer.getBean( "Jimmy" );
       BandMember Robert = ( BandMember )IOCContainer.getBean( "Robert" );
       BandMember John = ( BandMember )IOCContainer.getBean( "John" );
       BandMember Jones = ( BandMember )IOCContainer.getBean( "Jones" );
              
       System.out.println( "**** Test Band Member Beans****" );
       System.out.println( Jimmy.toString() );
       System.out.println( Robert.toString() );
       System.out.println( John.toString() );
       System.out.println( Jones.toString() );
                   
       Band LedZepplin = (Band) IOCContainer.getBean("Band");
       System.out.println( "**** Test Band Bean****" );
       System.out.println(LedZepplin);
      
    }
}

The test case simply tests all of the objects defined in IOC-application-context.xml. Our simplest object definitions are the BandMembers where we only a name parameter is set. Slightly more complex is the Band object which is composed of a few attributes and a reference to the BandMembers.

Below is the output that should be generated when you run the test case.

Test case output:

Member Name: Jimmy Page
Member Name: Robert Plant
Member Name: John Bonham
Member Name: John Paul Jones
**** Test Band Bean****
Name: Led Zeppelin
Label: Atlantic
Genre: Rock
Singer Member Name: Robert Plant
Bass Member Name: John Paul Jones
Guitarist Member Name: Jimmy Page
Drummer Member Name: John Bonham

Errors I ran into while writing the example:

java.lang.InstantiationException: fm.devhub.objects.BandMember
at java.lang.Class.newInstance0(Class.java:340)
at java.lang.Class.newInstance(Class.java:308)
at fm.devhub.objects.BandMember.main(BandMember.java:29)
Exception in thread "main" java.lang.NullPointerException
at fm.devhub.objects.BandMember.main(BandMember.java:30)

I ran into this error because i didn't use a default
constructor in my BandMember class.
The default constructor is automatically created
by java only when no other constructors
are present.

When is an IOC Container needed?

The answer to this question is going to vary depending on what you are trying to accomplish as well as your personal programming style and requirements.

Generally you should consider adding Dependency Injection and IOC Container functionality in the following scenarios:

  • You need to inject configuration data into an object (for example database connection configuration).
  • You need to inject different implementations of the same object.
  • You need to inject the same dependency into objects

Also, a very powerful side effect using an IOC Container and DI is that it caninherently simplify testing. Envision being able to mock up objects as needed for testing in your configuration (application context) file vs. having to connect to a database or call/stub a service. Also testing objects under multiple configurations is simple using DI and an IOC Container.

You do not need Dependency Injection in the following scenarios:

  • You will not need different configurations for an object.
  • You will not need different implementations for an object.

That said, IOC containers such as Spring IOC offer many useful features which are enabled by DI. After reading this article I would advise familiarizing yourself with Spring IOC (or any other main stream IOC framework) simply because it will give you better insight into best practices and industry standards for IOC implementations and testing approaches.

What are some popular IOC Containers?

  • Spring IOC
  • Pico Container

Download Example Source:
Click here to download example source.

Additional Reading:
Factory Pattern vs. Dependency Injection
Why do i need an IOC container as opposed to straightforward DI code
Martin Fowler: Injection

HTTP Request/Response Basics

The following introductory topics will be discussed in this article:

  • The life-cycle of an HTTP request & response.
  • Anatomy of an HTTP request & response.
  • HTTP Methods & best practices.
Figure 1: HTTP Request/Response

Figure 1: HTTP Request/Response

The life-cycle of an HTTP request commonly looks like this:

  1. A user visits the URL of a website.
  2. This creates a request which is routed to a web server via the internet (a network of DNS’s, routers and switches) over HTTP (Hypertext Transfer Protocol).
  3. The web server receives the HTTP request and responds to the user with the web page (or content) which was requested.

Every time you click on a link and visit a web page, behind the scenes you are making a request, and in turn receiving a response from a web server. Note that HTTP requests can be made via many channels, not just web browsers. For example, an HTTP request could be made using TELNET, or a client written in JAVA or C# etc.

To see an example of what an HTTP request and response looks like do the following:

  1. Go to the website http://web-sniffer.net/
  2. Type in www.google.com (or any website you wish) in the “HTTP(S)-URL:” input field. When you click on “Submit” you will see the HTTP request and response data for www.google.com.

The anatomy of an HTTP request:
As a web developer, an important area to understand is the method portion of an HTTP request. The method tells the web server what kind of request is being performed on a URI.
So if you type in the URL www.google.com/finance (for example). You are requesting the /finance URI. Within the /finance URI the HTTP request has to define an HTTP method.

The method portion of an HTTP request contains the following definition options:

       Method         = "OPTIONS"
                      | "GET"
                      | "HEAD"
                      | "POST"
                      | "PUT"
                      | "DELETE"
                      | "TRACE"
                      | "CONNECT"
                      | extension-method
       extension-method = token

OPTIONS
Options is useful for finding out which HTTP methods are accessible by a client. Depending on how the web server you are trying to connect to is configured, the administrator may only have the POST and GET HTTP methods accessible. While other HTTP methods such as DELETE, TRACE, etc are disabled.

GET
A GET request retrieves data from a web server by specifying parameters in the URL portion of the request. If you examine the example HTTP request below, we are asking for index.html, and passing the parameter report_id.

	GET /index.html?report_id=34543222 HTTP/1.1
	Host: www.awebsite.com
	User-Agent: Safari/4.0

Examples of when to use GET:

  1. You are accessing a URL purely for the sake of viewing data. You could think of it as using an SQL SELECT statement. You are asking for data from the web server without the intent of updating any data.
  2. You need a URL to be ‘bookmarkable’. Basically HTTP GET is considered to be repeatable, which allows requests to be retried safely and responses to be cached.
  3. You don’t mind the request being repeated. For example a user visiting the same URL more than once.

Examples of when not to use GET:

  1. You are passing sensitive data such as usernames, passwords, social security numbers, etc.
  2. You are sending large amounts of data. Although there isn’t a character limit defined in the HTTP specification for the length of a URL, IE 4 for example only supports a max URL length of ~2000 characters using a GET request.
  3. You need to update something on a server, for example submitting a form which will update a users address or shopping cart.

POST
A POST HTTP request utilizes a message body to send data to a web server. If you examine the example HTTP POST request below, you will see that we are passing a POST HTTP request with the message body of ‘userid=mo&password=mypassw’ to login.jsp (login.jsp would be an application that the web server forwards requests to).
Examples of when to use POST:

  1. You have a large amount of data to send to a web server (the size of data would exceed URL limits of the GET method).
  2. You are sending sensitive data such as uesrnames, passwords, social security numbers etc.
  3. You are altering the state of data in a web application. For example, a shopping cart keeping track of items which you are purchasing.

Examples of when not to use POST:

  1. The URL that you are passing has a requirement of being ‘bookmarkable’. If the state of the URL changes, then the user will not be able to retrieve, or view the data it it’s former state.
  2. Your request needs to be idempotent. Note that POST requests can be idempotent, however it’s better practice to use PUT (if this HTTP request method is supported by your web server and client)
	POST /login.jsp HTTP/1.1
	Host: www.awebsite.com
	User-Agent: Safari/4.0
	Content-Length: 27
	Content-Type: application/x-www-form-urlencoded

	userid=mo&password=mypassw

PUT
PUT similar to POST utilizes a message body to transfer data. However, there are some fundamental differences between the two. Firstly PUT is considered to be idempotent, secondly a PUT’s action is always defined for a specific URI, finally a PUT is for loading the data for that resource. In other words you should know the exact location of where the data you are sending will be retrieved later.
Example of when to use PUT:

  1. Put is idempotent, so basically if you need to accommodate for a scenario where a request is submitted multiple times but the result needs to be identical for each submission; use PUT. This could be useful for creating a new user for instance. If you send a PUT request to create a user Joe Smith multiple times, the last request should have the same results as if it were sent first.
  2. You have a specific URI which you are sending data to. For example:
POST URI:

http://hostname.com/users/new

PUT URI:

http://hostname.com/users/joesmith

Example of when not to use PUT:

  1. PUT should not be used for non idempotent requests (if the state of the resource is likely to change each time a request is sent).
  2. It’s good to keep in mind that in the case of html forms, most browsers do not support the PUT/DELETE methods. It is expected that POST/GET are used. Some Restful frameworks such as Ruby on Rails for example requires the use of PUT/DELETE, however these HTTP Methods are simply tunneled through the HTTP POST Method.
	PUT /somedatabase/some_doc_id HTTP/1.1
	Content-Length: 240
	Content-Type: application/json

	{
	  "Subject":"Resume",
	  "Author":"Mo",
	  "Body":"Find my resume attached"
	}

HEAD
The HTTP HEAD Method is used to retrieve information about a URL from a web server. So for example if you sent a HEAD request, you would receive a response from the web server containing the same information as you would with an HTTP POST excluding the body data. Here is an example:

	HEAD /de HTTP/1.1[CRLF]
	Host: www.google.com[CRLF]
	Connection: close[CRLF]
	User-Agent: Web-sniffer/1.0.37 [CRLF]
	Accept-Encoding: gzip[CRLF]
	Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7[CRLF]
	Cache-Control: no-cache[CRLF]
	Accept-Language: de,en;q=0.7,en-us;q=0.3[CRLF]
	Referer: http://web-sniffer.net/[CRLF]

DELETE
The HTTP DELETE method can be used to delete a resource from a server. Generally it is used in two scenarios. Fist scenario is if you are following RESTful standards in developing your web application. Secondly it can be used when DELETE is enabled on a web-server and you would like to follow the HTTP standard for deleting a resource. It’s important to note however that you can use HTTP POST to handle an HTTP DELETE action also, the decision is narrowed down to the options described above.

TRACE
If you attempt to execute an HTTP TRACE method on most web-servers you will likely see this message:

	Status: HTTP/1.1 501 Not Implemented

HTTP TRACE is used to eacho the contents of an HTTP Request back to the requester (which can be useful for debugging). This however may pose a security threat because malicious code can abuse HTTP TRACE functionality to gain access to information in HTTP headers such as cookies and authentication data, if an HTTP TRACE request is sent the original request data will be returned in addition to any user specific data. An example HTTP TRACE response can look like this:

	TRACE / HTTP/1.1
	Host: www.google.com

	HTTP/1.1 200 OK
	Server: Microsoft-IIS/5.0
	Date: Tue, 31 Oct 2012 03:01:44 GMT
	Connection: close
	Content-Type: message/http
	Content-Length: 39

	TRACE / HTTP/1.1
	Host: www.google.com

CONNECT
HTTP CONNECT can be used to establish a network connection to a web server over HTTP. It’s primarily used in cases where a secure/encrypted HTTP connection (tunnel) needs to be established between a client and a web server such as an SSL connection.
Simple HTTP tunnels are an unencrypted connection through an HTTP proxy to an arbitrary destination. The tunnel takes advantage of the HTTP CONNECT method normally used for HTTPS (secure web traffic) to connect to the destination server. A typical HTTPS connection through a proxy should look like:

	CONNECT remote-server:443 HTTP/1.0
	User-Agent: Mozilla/4.0 (compatible; MSIE 6.0;..
	Host: remote-server
	Content-Length: 0
	Proxy-Connection: Keep-Alive
	Pragma: no-cach

HTTP Response Codes
Whenever a request is made to an HTTP server, a response code is sent back to the client accompanying the requested data. It’s important to understand what these response codes are as they will be useful for managing errors in your web applications. A list of HTTP response codes and their meanings can be found here:
HTTP Response Codes

Additional Reading:
HTTP 1.1 specification
PUT vs. POST
HTTP TRACE Vulnerability Blog Post
Restful HTTP PUT/POST Article
HTTP CONNECT Security White Paper
TRA3EQ3SV99B

Thanks for reading! If you find any technical inaccuracies or deficiencies in this article, please make devhub.fm aware by posting a comment. Any feedback is welcome & encouraged.