The Spring Framework: Ep. 2 - The Context
From the previous episode:
In the previous episode, we discussed the Inversion of Control(IoC) principle. The Spring IoC container is responsible for creating and managing objects and their dependencies and providing those objects to the client code that uses them. Spring implements IoC through Dependency Injection. If you haven't read the previous article, I strongly encourage you to do it before going further.
What is Spring Context?
Understanding the basics of the Spring Context and how to use it effectively can significantly improve the design and functionality of your projects.
Spring Context is the container that manages the creation and lifecycle of the Spring Beans. So what is a Bean in the first place?
Spring Bean = Any class that we want to be managed by Spring.
What is the benefit? Once a class is a Bean, it means that we can use dependency injection to inject it into other objects.
Let's take a look at the NotificationSender defined in the previous article:
public class NotificationSender {
private SmsSender smsSender;
public NotificationSender(SmsSender smsSender) {
this.smsSender = smsSender;
}
}
If NotificationSender
and SmsSender
are Spring Beans, the framework will instantiate them on our behalf. It is smart enough to see that the NotificationSender constructor needs an instance of the SmsSender and will provide one. The control is inverted. Spring creates objects, and we receive them when needed.
As you can see in the diagram above, our application consists of Spring-managed objects(beans) and unmanaged objects(plain java objects).
Creating the context
But more on beans in the following episodes. Let's focus on the context for now. As we said, the context refers to the container that holds the beans. So what exactly is this context? Although it sounds complicated, in the end, it's just a class that implements the org.springframework.context.ApplicationContext
interface. Spring is providing a few implementations of this interface. Here are some of them:
ClassPathXmlApplicationContext - the context is created based on an XML configuration file taken from the classpath;
FileSystemXmlApplicationContext - the context is created based on an XML configuration file taken from the filesystem;
AnnotationConfigApplicationContext - the context is configured via annotations;
So there are two possibilities to configure the context: using XML config files or using Java annotations. Which one is better? Spring documentation says we should prefer the annotations approach. So this is what I will teach you here. This is considered the modern approach. However, I know there are many projects out there that are still using XML configs. If you are interested, you can check the official documentation because it covers this topic well.
Demo
I am going to create a new Gradle project using Intellij Idea. For our purpose, the build system doesn't matter. You can use Maven if you prefer it. Maven and Gradle are used to manage the dependencies of our application.
The first step is to add spring-context dependency in build.gradle
.
dependencies {
implementation 'org.springframework:spring-context:5.3.24'
}
Then let's create a Main class:
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); Arrays.stream(applicationContext.getBeanDefinitionNames())
.forEach(System.out::println);
}
}
Here we instantiate a new AnnotationConfigApplicationContext context. Then we use the getBeanDefinitionNames()
method to print all the beans available in the context.
When running the application, you should see something like this:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
The context contains four beans used internally by Spring. The final version of the application is available here.
Conclusion
In conclusion, the Spring context is an essential component of the Spring Framework that provides a way to manage the lifecycle and configuration of beans in a container. It allows for easy integration with other Spring modules and third-party libraries, making it a powerful tool for building robust and maintainable applications.
👉 In the next episode, we will see how to define a bean using Java annotations. Stay tuned!