What is a Spring Container?
Spring applications have a special data structure called the Spring Container(container for short). The objects that are managed by this container are called Spring-managed beans or components. The container does three critical tasks.
Create
Manage the Spring-managed beans
Configure and resolve the dependencies between components
It is also important to note that, not all objects are inside the Spring container and there can be several objects outside the Spring container, such as strings.
Start Container
As we discussed in the previous article, when we generated a new Spring Boot project with the name Demo, the Spring Initializr generated a class named, DemoApplication
with a main(..)
method. And, in the body of the main(...)
method, there is run(…)
call, which starts up the container.
@SpringBootApplication
public class DemoApplication{
public static void main(String args[]){
SpringApplication.run(DemoApplication.class, args);
}
}
This run(…)
method is a static method of the SpringApplication
class. As shown above, two arguments have been passed to the run(…)
method: the initial configuration, which is the type of your class, and the arguments passed to the main(…)
method. If these arguments weren’t passed, Spring wouldn’t be able to get the arguments we pass on the command line.
Alternate Ways to Start Container
Rather than using the static run(…)
method, we can also create an object of SpringApplication
and later use the run(…)
method. With this, we are capable of adding some settings to the SpringApplication
object.
@SpringBootApplication
public class DemoApplication{
public static void main(String args[]){
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setHeadless(false);
app.setBannerMode(Banner.Mode.OFF);
app.setLogStartupInfo(false);
// More initializations
app.run(args);
}
}
Rather than creating a SpringApplication
object, we can use the SpringApplicationBuilder
to create our SpringApplication
object by following the builder pattern as well.
@SpringBootApplication
public class DemoApplication{
public static void main(String args[]){
new SpringApplicationBuilder(DemoApplication.class)
.headless()
.bannerMode(Banner.Mode.OFF)
.logStartupInfo(false)
.run(args);
}
}
Although both of these alternatives look similar, there are two small differences.
With
SpringApplicationBuilder
, you can only set states, you cannot read them, meaning there are no getters. However, inSpringApplication
there are setters and getters, but the getters are rarely needed.In
SpringApplicaionBuilder
, hierarchical contexts can be set. In a hierarchical context, parents, children, and siblings can be modeled to have an isolated container.
Application Context
The run(…)
method returns an application context, which represents the Spring container that holds all the beans created by the application. This can be stored in a variable and used later.
ConfigurableApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);
This ConfigurableApplicationContext
is an interface that extends other interfaces.
We can also use ApplicationContext
interface as well. The advantage of defining this kind of variable is that we are able to use the context methods defined in those interfaces. For instance, if we want to get a sorted list of all registered components, we can use the ApplicationContext
as shown below.
ApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);
Arrays.stream(ctx.getBeanDefinitionNames())
.sorted()
.forEach(System.out::println);
Spring Boot Auto-Configuration
This feature is the main difference between Spring Boot and Spring Framework. With Spring Framework, we have to configure everything, but with Spring Boot components are automatically registered thanks to auto-configuration. For example, our application, DemoApplication is automatically instantiated as an object and placed in the container. Also, it is automatically named, in lowercase and not capitalized like the class name(demoApplication).
Interface ConfigurableApplicationContext
extends ListableBeanFactory
. And ListableBeanFactory
extends BeanFactory
. In there, we can find methods for taking Spring-managed beans and for existence tests.
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);
DemoApplication bean = ctx.getBean(DemoApplication.class);
}
}
This may either return the bean or an exception if the bean cannot be provided.
So this is it regarding Spring Container. In the next article, we’ll check about Picking Up Spring-Managed Beans through Class Path Scanning.