AbstractController
This class provides the basic building blocks for all other Controllers. You shouldn’t have to
implement your own Controllerclass, as this class is built for subclassing.
The first thing to notice about this class is that it marks the handleRequest()method
(from the Controllerinterface) as final. At first glance, this seems to make the class useless
for subclasses. Looking closer, we see a protectedmethod named handleRequestInternal(),
clearly intended for subclasses. Why not just allow overriding of the handleRequest()method?
The answer, in short, is because this class obeys the Open-Closed Principle.
Each Controllerin the hierarchy defines a clear work flow and life cycle. For instance, the
AbstractControllerwill
- check whether the HTTP request method (GET, POST, etc) is supported by this
Controller; - check whether a session exists, if this Controllerrequires a session;
- send cache control headers, if required;
- synchronize around the session, if required;
- run custom logic, via handleRequestInternal().
The first four steps are well defined, and each subclass relies on them to run in a well-known
manner. In other words, they should never change, because if they did, the very definition of
AbstractControllerchanges. For this reason, the class marks the handleRequest()method as
final, to be closed for modification. This class’s work flow is now set in stone, so to speak.
Of course, if the class only performed the first four items, it wouldn’t be of much use. To
be open for extension, it defines a handleRequestInternal()method specifically for subclasses
to have a well-known extension point to place custom logic. This way, subclasses are free to
customize this class without the possibility of changing its well-defined work flow. This is a
perfect manifestation of the Open-Closed Principle, and you will see many examples of it
throughout the Controllerhierarchy.
This example also illustrates the Template pattern, a popular design pattern also found
throughout the Spring Framework. The Template pattern is used to separate the variant
sections of an algorithm from the invariant sections to allow for easy customization and
substitution. In other words, a template of the algorithm is created, with the specifics
intended to be filled in later.
The AbstractController’s implementation of handleRequest()applies the Template pat-
tern, as it defines a well-known work flow (the algorithm) but provides an extension point for
specifics via the handleRequestInternal()method. This pattern is another perfect example of
the Open-Closed Principle, and you can find it across the Spring Framework from Spring MVC
to Spring JDBC.
AbstractController Functionality
By examining the work flow of AbstractController, we will see the common functionality that
is applied to all Controllers.
118 CHAPTER 6 ■THE CONTROLLER MENAGERIE