Spring Certification: Container, Dependency and IOC | Reviewing the Study Guide
By: Micheal Arsenault
Posted: December 24, 2020| Modified: December 26, 2020
Reading Time: 7 minutes
Tags: certification Java Spring
resources:
-
Spring Professional Documentation - Web Servlet
- Much of the content from Servlet and the react WebFlux cross over, and both of these documents contain references to each other; however, because of some fundamental differences of the underlying architecture there are also considerable differences.
The first section of the Study Guide is ‘Container, Dependency and IOC’ and I’m going to try and follow with that guided overview of material.
Container, Dependency and IOC
What is dependency injection and what are the advantages of using it?
To begin, let’s look at the ultimate source of human knowledge, Wikipedia!
Basically here, instead of us calling the ‘new’ keyword in our code, we tell Spring that we need something and it will give it to us. This has numerous benefits that relate to better OO & SOLID principles:
- Improves:
- Testability because external dependencies can be more easily mocked or stubbed.
- Clarity of the code because it’s responsibilities have been narrowed.
- Cohesion of class’s interacting with each other as this design promotes coding by contract [Java Interfaces]
- Maintenance as there is a clearer seperation of concerns the code is handling
What is an interface and what are the advantages of making use of them in Java?
A Java interface let’s you expose just the functionality you’d like to expose to it’s users while hiding the more complicated implementation details. This also allows for different implementations to be used as well, preventing a lock-in of one implementation. So why does this matter? Again you can provide easier testing through mocks, as well as provide different levels of functionality by different implementations.
What is an ApplicationContext?
OK! So we are finally getting to some Spring specific elements. At it’s core Spring is an Inversion of Control framework and it handles creating and instantiating the resources needed for your application. Spring will take in your Java as well as configuration metadata, this can be through @annotations that are applied throughout your java codebase, and provide you with fully instantiated objects ready to use throughout your application.
Source: Spring Core Doc
How are you going to create a new instance of an ApplicationContext?
In the below example you would provide Spring a set of classes that have Spring configuration metadata and from this you can pull out fully instantiated objects.
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
It should also be noted that you can instantiate a container and then provide metadata configuration after initial instantiation:
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class, OtherConfig.class);
ctx.register(AdditionalConfig.class);
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
This also ignores the creating of any Servlet Application Context containers!
With Spring you can use the web.xml configuration
<web-app>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
or the newer 3.0+ Servlet configuration
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { App1Config.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/app1/*" };
}
}
Also, while I’ve note mentioned any of the actual configuration metadata process, you have the option to have a package be scanned for Java classes that can be used; however, it’s important to note this is NOT A ZERO COST operation as scanning through large code bases will take time every time the application starts. Therefore, you should use scanning appropriately on code that would be picked up at least in a majority sense, and provide scoping or ignore rules to prevent unnecessary work.
Can you describe the lifecycle of a Spring Bean in an ApplicationContext?
Alright, this is a large and slightly tricky question, but it’s only tricky because there’s a lot of little steps that a bean will take in order to be fully prepared.
On a way zoomed back view, you can think of a bean being created like this: 1. Spring Container reviews configuration metadata and creates bean ‘recipes’ that will be instantiated later. 2. Spring processes additional configuration metadata that will affect how beans are created and additional capabilities, thereby altering the ‘recipe’ for beans. 3. Spring creates the beans providing resources of already created beans in order to fulfill dependencies. 4. Spring provides the ready made beans to be used 5. SHUTDOWN hooks inside the container object trigger shutdown operations that cascade custom
Now this is a way oversimplification of the process that actually occurs. I really recommend reviewing the actual documentation as there’s quite a few steps involved, and each step has a lot of detail.Spring core - beans-definition
You should also be aware of the differences in making changes to bean instances after they’re created and modifying the bean metadata ‘recipe’
While this step is a very fundamental building block of the bean instantiation process, in a general sense it’s hidden from you in most cases except through interacting with either definition
Here are some additional resources to review on this as it’s a rather spread out topic in the framework documentation:
-
dZone article – this article has a good picture of what the process looks like.