Spring Professional Study Notes
Before we get down to my own additions to existing resources mentioned in my certification guide post I would like to reiterate all resources that I used for my preparation:
- Course-ware
- Spring in Action, Third Edition by Craig Walls
- Jeanne’s study notes
- Spring Framework Reference Documentation
Bean life-cycle
Bean initialization process
One of the key areas of the certification is the life-cycle management provided by Spring. By the time of the exam you should know this diagram by heart. This picture describes the process of loading beans into the application context. Starting point is definition of beans in beans XML file (but also works for programmatic configuration as well). When the context gets initialized all configuration files and classes are loaded into the application. Since all these sources contain different representations of beans there needs to be a merging step that unifies bean definitions into one internal format. After initialization of whole configuration it needs to be checked for errors and invalid configuration. When the configuration is validated then a dependency tree is built and indexed.
As a next step, Spring applies BeanFactoryPostProcessors
(BFPP from now on). BFPP allows for custom modification of an application context’s bean definitions. Application contexts can auto-detect BFPP beans in their bean definitions and apply them before any other beans get created. Classic examples of BFPPs include PropertyResourceConfigurer
and PropertyPlaceHolderConfigurer
. When this phase is over and Spring owns all the final bean definitions then the process leaves the ‘happens once’ part and enters ‘happens for each bean’ part.
Please note that even though I used graphical elements usually depicting UML elements, this picture is not UML compliant.
When in second phase, the first thing that is performed is the evaluation of all SPEL expressions. The Spring Expression Language (SPEL for short) is an expression language that supports querying and manipulating an object graph at runtime. Now, that all SPEL expressions are evaluated, Spring performs dependency injection (constructor and setter). As a next step Spring applies BeanPostProcessors
(BPP from now on). BPP is a factory hook that allows for custom modification of new bean instances. Application contexts can autodetect BPP beans in their bean definitions and apply them to any beans subsequently created.
Calling postProcessBeforeInitialization
and postProcessAfterInitialization
provides bean life-cycle hooks from outside of bean definition with no regard to bean type. To specify bean life-cycle hooks that are bean specific you can choose from three possible ways to do so (ordered with respect to execution priority):
@PostConstruct
- Annotating method with JSR-250 annotation
@PostConstruct
- Annotating method with JSR-250 annotation
afterPropertiesSet
- Implementing
InitializingBean
interface and providing implementation for theafterPropertiesSet
method
- Implementing
init-method
- Defining the
init-method
attribute of bean element in XML configuration file
- Defining the
When a bean goes through this process it gets stored in a store which is basically a map with bean ID as a key and bean object as a value. When all beans get processed the context is initialized and we can call getBean
on the context and retrieve bean instances.
Bean destruction process
Whole process begins when ApplicationContext
is closed (whether by calling method close
explicitly or from container where the application is running). When this happens all beans and the context itself are destroyed. Just like with bean initialization, Spring provides life-cycle hooks for beans destruction with three possible ways to do so (ordered with respect to execution priority):
@PreDestroy
- Annotating method with JSR-250 annotation
@PreDestroy
- Annotating method with JSR-250 annotation
destroy
- Implementing
DisposableBean
interface and providing implementation for thedestroy
method
- Implementing
destroy-method
- Defining the
destroy-method
attribute of bean element in XML configuration file
- Defining the
However there is one tricky part to this. When you are dealing with prototype bean an interesting behavior emerges upon context closing. After prototype bean is fully initialized and all initializing life-cycle hooks are executed, container hands over the reference and has no reference to this prototype bean since. This means that no destruction life-cycle hooks will be executed.
Request processing in Spring MVC
When it comes to Spring MVC it is important to be familiar with basic principals of how Spring turns requests into responses. It all begins with ContextLoaderListener
that ties the life-cycle of the ApplicationContext
to the life-cycle of the ServletContext
. Then there is a DelegatingFilterProxy
which is a proxy for standard servlet filter delegating to a Spring-managed bean implementing javax.servlet.Filter
interface. What DelegatingFilterProxy
does is delegate the Filter
‘s methods through to a bean which is obtained from the Spring application context. This enables the bean to benefit from the Spring web application context life-cycle support and configuration flexibility. The bean must implement javax.servlet.Filter
and it must have the same name as that in the filter-name
element.
DelegatingFilterProxy
delegates all mapped requests to a central Servlet that dispatches requests to controllers and offers other functionality that facilitates the development of web applications. Spring’s DispatcherServlet
however, does more than just that. It is completely integrated with the Spring IoC container. Each DispatcherServlet
has its own WebApplicationContext
, which inherits all the beans already defined in the root WebApplicationContext. WebApplicationContext
is an extension of plain old ApplicationContext
that owns few specific beans. These beans provide handy bundle of tools I named ‘Common things’ that include support for things like: resolving the locale a client is using, resolving themes of your web application, mapping of exceptions to views, parsing multipart request from HTML form uploads and few others.
After all these things are taken care of, DispatcherServlet
needs to determine where to dispatch incoming request. In order to do so DispatcherServlet
turns to HandlerMapping
which (in turn) maps requests to controllers. Spring’s handler mapping mechanism includes handler interceptors, which are useful when you want to apply specific functionality to certain requests, for example, checking for a principal.
Please note that even though I used graphical elements usually depicting UML elements, this picture is not UML compliant.
Before the execution reaches the controller there are certain steps that must happen like resolving various annotations. The main purpose of a HandlerAdapter
is to shield the DispatcherServlet
from such details. The HandlerExecutionChain
object wraps the handler (controller or method). It may also contain a set of interceptor objects of type HandlerInterceptor
. Each interceptor may veto the execution of the handling request.
By the time execution reaches a controller or method, HandlerAdapter
has already performed dependency injection, type conversion, validation according to JSR-303 and so on. When inside controller, you can call bean methods just like from any standard bean in your application. When controller finishes its logic and fills Model with relevant data, HandlerInterceptor
retrieves a string (but could be a special object type as well) that is later resolved to a View
object.
In order to do so, Spring performs mapping of returned string to a view. Views in Spring are addressed by a logical view name and are resolved by a view resolver. In the end, Spring inserts the model object in a view and renders the results which are in turn returned to the client in form of response.
Remote method invocation protocols
When it comes to remote method invocation and the protocols it supports, it is useful to know basic properties and limitations of said protocols.
Protocol | Port | Serialization |
---|---|---|
RMI | 1099 + ‘random’ | IO Serializable |
Hessian | 80 + 443 | Binary XML (compressed) |
Burlap | 80 + 443 | Plain XML (overhead!) |
HttpInvoker | 80 + 443 | IO Serializable |
Reference: | Spring Professional Study Notes from our JCG partner Jakub Stas at the Jakub Stas blog. |
Thanks for such awesome post.It helped to clear my doubts.
Nice Post. Thank You !!