The Spring ApplicationContext explained

The Spring ApplicationContext provides developers direct access to the Spring framework’s Inversion of Control (IoC) container.
The ApplicationContext represents the heart and soul of Spring, as it makes features such as dependency injection, autowiring and Spring bean lifecycle management possible.

How does the Spring ApplicationContext work?

In order to benefit from Spring’s IoC container, developers must access their Java components through Spring’s ApplicationContext. When a Java component is obtained through Spring’s ApplicationContent, it is colloquially referred to as a Spring Bean.
When developers get Java components from the Spring ApplicationContext, they gain access to various productivity enhancing features including:
  • Dependency injection and autowiring
  • Spring bean lifecycle management
  • Simplified property file access
  • Access to container triggered events
  • Use of Spring’s Inversion of Control (IoC) features

How to access Spring’s ApplicationContext

The Spring IoC container eliminates the need to instantiate Java components with the new keyword.

Without Spring, if a developer wanted an instance of a HappyMeal, they’d normally write code like this:
HappyMeal happyMeal = new HappyMeal();
However, with the ApplicationContext, the developer asks the Spring IoC container for the instance instead:
ApplicationContext context = SpringApplication.run(App.class, args);
HappyMeal happyMeal = context.getBean(HappyMeal.class);

Full Spring ApplicationContext example

If you think going through the Spring ApplicationContext seems like a lot of work to obtain an instance of a class, especially when a call to the Java class’ constructor would suffice, you’d be right.
In fact, to fully implement the example above, the HappyMeal class would require a special @Component annotation so that the Spring framework would be aware of it.
@Component
public class HappyMeal  { }
Furthermore, the class referenced by the run method would
(Alternatively, the more modern @SpringBootApplication annotation could be used on the instead, as it envelops both @Configuration and @ComponentScan, while providing additional, enterprise-ready functionality.)
//@Configuration
//@ComponentScan("com.mcnz.spring.ioc")
@SpringBootApplication
public class App {
  public static void main(String args[]) {
    ApplicationContext context = SpringApplication.run(App.class, args);
    HappyMeal happyMeal = context.getBean(HappyMeal.class);
  }
}

The Spring ApplicationContext is worth it!

Don’t let the additional overhead of setting up the Spring framework and obtaining the ApplicationContext dissuade you from embracing the framework. Fortunately, setting up the Spring ApplicationContext:
  • Is something that only needs to be done once when the project starts
  • Is standard, boilerplate code that is easily copied reproduced
  • Is largely hidden from developers when Spring Boot is used
The industry-wide prevalence of Spring Boot and Spring’s ApplicationContext backed IoC container is proof of the fact that the overhead of setting up the framework is well worth the benefit.

When should you use the Spring IoC container?

Delegating the lifecycle management of your Java components to Spring’s IoC container brings with it many benefits, but that doesn’t mean every JavaBean should be pulled from Spring’s ApplicationContext.
The use of the Spring IoC container only makes sense in situations where the object needed:
  • Interacts with a separate layers of your application
  • Is heavily customizable through parameters
  • Represents a plugability point in your application
  • Is loosely coupled to the application through an interface
  • Might be substituted during testing or deployment

Spring ApplicationContext types

The example given above actually demonstrates the creation of a Spring ConfigurableApplicationContext , which is the type of object returned from the run method.
For developers experimenting with Spring Boot or just learning about Spring IoC, an annotation based approach to configuring Spring makes the most sense.
However, there are other ways to obtain the ApplicationContext, with five of the most popular approaches being:
  • AnnotationConfigApplicationContext – used when the configuration is primarily annotation based (demonstrated above)
  • XmlWebApplicationContext – allows XML based Spring configuration to be combined with a Servlet based web application
  • AnnotationConfigWebApplicationContext – like its XML-based counterpart, this component is often used in Spring MVC web apps
  • FileSystemXMLApplicationContext – this class loads an XML-based Spring configuration file from the file system
  • ClassPathXmlApplicationContext – this class looks for an XML-based Spring configuration file on the JVM’s runtime classpath

Annotation vs XML-based Spring configuration

Before Java annotations became part of the JDK, all Spring configuration was done via an XML based configuration file.
A sample Spring ApplicationContext configuration through an XML file is shown below.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean id="happyMeal" class="com.mcnz.spring.ioc.HappyMeal">
    <constructor-arg name="pepsiCola" ref="pepsiBean" />
  </bean>
  <bean id="pepsiBean" class="com.mcnz.spring.ioc.PepsiCola" />
</beans>

Spring XML files

This Spring ApplicationContext example builds on the concept of Inversion of Control and performs an additional function known as dependency injection. To accomplish this, this example creates two beans:
  • A pepsiBean which is an instance of the PepsiCola class
  • A happyMean bean that is given a pepsiCola through the Spring IoC container’s dependency injection feature.
A similar feat could be achieved with annotations as well if:
  • The cola class is decorated with a @Component annotation
  • Spring’s @Autowired annotation is used to perform property injection
@Component
public class CocaCola { }

@Component
public class HappyMeal  {
  @Autowired
  CocaCola cocaCola;
}

When to use XML-based Spring configuration

On simple projects, an annotation based approach to Spring ApplicationContext configuration is preferred.
However, as programs grow in size, annotation bloat becomes a real issue, as methods can have more annotations than they do lines of code.
On larger projects, an XML-based Spring confiuration is sometimes preferred.
Furthermore, when Spring configuration is externalized in an XML file, recompilation of the code is not required in order to change how the Spring ApplicationContext is wired.

Spring ApplicationContext vs BeanFactory

When maintaining older code, or looking at older Spring tutorials, developers may see references to the BeanFactory class, rather than the ApplicationContext.
The BeanFactory is the predecessor to the ApplicationContext, and while it was often accessed directly in the past, references to it should never appear in new projects.
The Spring ApplicationContext extends the BeanFactory interface, so it encompasses all of the functionality of the BeanFactory, while providing additional behaviors enterprise-scale applications will need.

Cameron McKenzie

Cameron McKenzie is an AWS Certified AI Practitioner, Machine Learning Engineer, Solutions Architect and author of many popular books in the software development and Cloud Computing space. His growing YouTube channel training devs in Java, Spring, AI and ML has well over 30,000 subscribers.