Spring Foundation(1) -- IoC and IoC Container

Spring Foundation(1) – IoC and IoC Container

1. What is IoC?

IoC (inversion of control) is an abstract concept, meaning that let “high level” decides “low level” instead of “low level” decides “high level”.

In software engineering, this abstract concept normally just refers to let a “third party” to help us create objects and manage their dependencies , in which context the so called third party is the IoC Container and the process that IoC Container helps to create and manage objects is called Dependency Injection(DI).

2. Why we need it

This might be confusing, so let’s see an example to have a clearer understanding. Imagine one scenario that you have 5 classes A - E, where Class A depends on Class B and Class B depends on Class C and so on. Let’s say Class E has a field e, so in Class D there should be a line of code new ClassE('valueOfe'), then in Class C, still you have to have a line of code saying new ClassD('valueOfe') right? Same thing happens in Class A and B. To be more specific:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Class E{
private int e;
E(int e){
this.e = e;
}
}

Class D{
private E objectE;
D(int valueOfIntE){
this.objectE = new E(valueOfIntE);
}
}

Class C{
private D objectD;
C(int valueofIntE){
this.objectD = new D(valueOfIntE);
}
}

...
...

This means that when the value of e in Class E changes, all the classes need to be updated. In reality development, this kind of dependency can be hundreds of classes, which is almost impossible to be manually updated one by one.

This is why IoC, or we can say, DI is useful. In the above code, the inconvenience comes from the problem that the highest level Class A depends on low level classes, which means that we have to manually new objects in our code. But DI can release us from “newing” objects in our code. Instead, we just need to say what object we require and then the IoC container will give it to us. In this way, the code would become as following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Class E{
private int e;
E(int e){
this.e = e;
}
}

Class D{
private E objectE;
D(E e){
this.objectE = e;
}
}

Class C{
private D objectD;
C(D d){
this.objectD = d;
}
}

...
...

As seen in the code, after using DI, all the objects is provided by the container. Then if the value of e changes at this time, there is no other objects needed to be updated. And this is the so called “Inversion of Control”, previously the “highest level” Class A depends on low level classes. But now the situation changed, it has become to low level classes are injected to high level Class A.

The benefit that IoC can give include: Decoupling, improve code reusable, and improve convenience of unit test.

3. How does it work?

After knowing the why we need IoC in software engineering, there is still one question remains: how does the system know the dependency relationship between objects? Also, how does the system know which class should be managed by it instead of ourselves? In the context of Spring framework, this work is done by the IoC Service Provider.

IoC Service Provider

IoC Service Provider is an abstract concept, and the so called Ioc Container is exactly an IoC Service Provider. It has two main responsibilities: 1) create the object, 2) manage the dependencies between objects. The basic principle is that we do some configuration works to tell the container what classes need to be managed by it and what’s the dependency relationships between them. Then, the container will help us do the job.

Three ways of configuration is acceptable in Spring framework: coding, configuration file, or annotation. Details will be introduced later.

4. IoC Container

The term container might be confusing and abstract, but it is actually nothing but a running environment. You can say it set of libraries that provides some functions or a context where the application-related information can be automatically managed and stored.

As discussed earlier, the IoC container is an IoC Service Provider that can manage and create objects, but in fact the IoC container has much more other functionalities such as providing the AOP support, Object Lifecycle Management, and Thread Management. Spring framework provides two types of containers : BeanFactory and ApplicationContext.

BeanFactory VS ApplicationContext

The term “bean” just means nothing special but object. So the work of BeanFactory is just generate beans to you. There are only two responsibilities it has: create beans and manage dependencies. In other words, you only need to tell the BeanFactory what object you want, and it will return it for you.

BeanFactory uses Lazy-load strategy, which means it initiates object and inject dependencies to it only when this object is needed. This means BeanFactory has a faster speed when the container is initiated. Therefore, in the situation where the resource is limited and there is no strict requirement about the functionalities, BeanFactory would be a good choice.

In contrast, ApplicationContext has more functionalities than BeanFactory. It indirectly inherent from the BeanFactory and thus has all functionalities that BeanFactory has, and provide more functionalities such as Event Publish etc. Unlike BeanFactory, ApplicationContext initiate all objects and inject dependencies to them as soon as the container is initiated, which means the initiating speed is lower. It fits the situation where you have enough resource and has needs more functionalities.

Created by Shain Melbourne, Australia.