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:
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.
@Componentpublic 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.)
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.
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
@Componentpublic class CocaCola { }@Componentpublic 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.