In Spring, one of the core concepts is the Inversion of Control (IoC) container. The IoC container is responsible for managing the lifecycle and configuration of application objects. It allows for dependency injection, which helps to decouple the components of the application, making it more maintainable, testable, and flexible.
In this chapter, we will learn about the IoC container in Spring, the two main types of IoC containers, and how to use them.
Inversion of Control (IoC) refers to the reversal of the flow of control in a system. Instead of the programmer controlling the flow of execution, the framework (in this case, Spring) controls the flow and the creation of objects.
In traditional programming, objects are created directly by using
new
or constructors. With IoC, Spring manages object
creation, and these objects are injected where they are needed. This
helps in promoting loose coupling between components.
Spring provides two main types of IoC containers:
The BeanFactory
container is the simplest and most
lightweight container. It uses the Factory Design
Pattern to manage beans. BeanFactory
is used when
the application has minimal requirements and doesn’t need complex
features.
Example:
= new XmlBeanFactory(new FileSystemResource("beans.xml"));
BeanFactory factory = (MyBean) factory.getBean("myBean"); MyBean myBean
The ApplicationContext
is the more commonly used
container and extends BeanFactory
. It provides more
features, such as event handling, AOP (Aspect-Oriented Programming), and
internationalization support. It is more suitable for most Spring
applications.
ApplicationContext
can be loaded using various types of
configuration, such as:
ClassPathXmlApplicationContext
)AnnotationConfigApplicationContext
)Example:
= new ClassPathXmlApplicationContext("beans.xml");
ApplicationContext context = (MyBean) context.getBean("myBean"); MyBean myBean
The workflow of the IoC container can be broken down into the following steps:
In this section, we will demonstrate how to use the
ApplicationContext
container to load and manage beans.
Let’s use the HelloWorldService
class from the previous
example as a Spring bean and manage it using
ApplicationContext
.
AppConfig.java
Configuration
Class:package com.example.springapplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public HelloWorldService helloWorldService() {
return new HelloWorldService();
}
}
Here, the @Configuration
annotation marks this class as
a configuration class, and the @Bean
annotation tells
Spring to treat the helloWorldService()
method as a Spring
bean.
Now, in the MainApp.java
class, we will load the
ApplicationContext
and retrieve the bean.
package com.example.springapplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApp {
public static void main(String[] args) {
// Initialize Spring IoC container
= new AnnotationConfigApplicationContext(AppConfig.class);
AnnotationConfigApplicationContext context
// Retrieve the bean from the container
= context.getBean(HelloWorldService.class);
HelloWorldService helloWorldService
// Call the method on the bean
.sayHello();
helloWorldService
// Close the context
.close();
context}
}
In this example, we are using the
AnnotationConfigApplicationContext
class to load the
configuration (AppConfig.class
), which contains the bean
definition for HelloWorldService
.
Spring IoC container is responsible for managing the lifecycle of beans. The lifecycle can be broken into several stages:
BeanPostProcessor
interface can be used to manipulate beans after they are instantiated
but before they are used.InitializingBean
interface or has a custom
init-method
, it will be called after the dependencies are
injected.DisposableBean
interface or has a custom
destroy-method
, it will be called when the container is
closed.Spring provides the @PostConstruct
and
@PreDestroy
annotations to handle bean initialization and
destruction in a more declarative way.
Spring supports several bean scopes, which determine the lifespan and visibility of the bean within the IoC container. The main scopes are:
Example of defining a bean with a scope:
@Bean
@Scope("prototype")
public HelloWorldService helloWorldService() {
return new HelloWorldService();
}
In this chapter, we learned about the IoC container
in Spring. The IoC container is responsible for managing the lifecycle
of beans and providing dependency injection. We also
explored the two main types of containers (BeanFactory
and
ApplicationContext
), their configuration, and usage.
Additionally, we discussed the bean lifecycle,
scopes, and lifecycle management
features provided by Spring.
In the next chapter, we will dive deeper into Bean Definitions and explore how Spring manages beans.
Are you ready to continue to the next chapter?