Container versus Context
You may have noticed in this chapter’s example how we keep referring to the code
that contains our object definitions as a container, and yet, the class used to create it
is called ApplicationContext. This chapter will clarify the differences between a
context and a container.
Spring Python has a base class called ObjectContainer, which is responsible
for managing the object definitions, creating instances of objects based on these
definitions, and is largely responsible for the functionality that we have looked at
so far. Any instance of this class would be a container in object oriented terms. In
fact, we could substitute that class in our previous example everywhere we see
ApplicationContext, and it would act mostly the same.
ObjectContainer has a subclass called ApplicationContext. An instance of
ApplicationContext is a context. However, from an OOP perspective, a context is
a containe r. So generally referring to instances of either one as an IoC container is
common practice.
An ApplicationContext has some differences in behavior from an
ObjectContainer as well as extra features involving life cycle management and
object management. These differences will first be shown in the following table of
features and will be covered in more detail later.

Lazy objects
Earlier I said that most of the behavior in this chapter’s example would be the same
if we had replaced ApplicationContext with ObjectContainer. One difference
is that ObjectContainer doesn’t instantiate any objects when the container is
first created. Instead, it waits until the object is requested to actually create it.
ApplicationContext automatically instantiates all objects immediately when
the container is started.
In the examples so far, this difference would have little effect, because
right after creating a container, we request the principle object. This won’t
be the case with some of the examples later in this book.
It is possible to override this by setting lazy_init to True in the object’s definition.
This will delay object creation until first request.
class WikiTestAppConfig(WikiProductionAppConfig):
def __init__(self):
super(WikiTestAppConfig, self).__init__()
@Object(lazy_init=True)
def data_access(self):
return StubDataAccess()
One reason for using this is if we had some object that was only needed on certain
occasions and could incur a lot of overhead when created. Setting lazy_init to
True would defer its creation, making it behave as an on-demand service.
This override works for both ObjectContainer and ApplicationContext.
Scoped objects
Another key duty of the container is to also manage the scope of objects. This means
at what time that objects are created, where the instances are stored, and how long
before they are destroyed.
Spring Python currently supports two scopes: singleton and prototype.
A singleton-scoped object is cached in the container until shutdown. A
prototype-scoped object is never stored, thus requiring the object factory to
create a new instance every time the object is requested from the container.
When a singleton object includes a prototype object as one of its
initializing properties, it is important to realize that the prototype
isn’t recreated every time the cached singleton is used.
The default policy for the container is to make everything singleton. The scope for
each object can be individually overridden as shown below.
class WikiTestAppConfig(WikiProductionAppConfig):
def __init__(self):
super(WikiTestAppConfig, self).__init__()
@Object(scope=scope.PROTOTYPE)
def data_access(self):
return StubDataAccess()
Each request for data_access will yield a different instance. This happens whether
the request is from outside the container, or from another container object injecting
data_access.
This override works for both ObjectContainer and ApplicationContext.
Property driven objects
ApplicationContext will invoke after_properties_set() on any object that has
this method, after it has been created and all container-defined properties have been
set. Here are some examples of how this can be useful:
- Including validation logic in class definitions. If some properties are optional
and others are not (or certain combinations of properties need to be set), this
is our opportunity to define it, and let the container validate that an object
was defined correctly. - Starting up background services. For example, PyroServiceExporter
launches a daemon thread in the background after all properties are set.
Post processor objects
ApplicationContext will search for post processors. These are classes
that manipulate other objects in the container. They extend Spring Python’s
ObjectPostProcessor class.
class ObjectPostProcessor(object):
def post_process_before_initialization(self, obj, obj_name):
return obj
def post_process_after_initialization(self, obj, obj_name):
return obj
When the context starts up, all non-post processors are fed one-at-a-time to each post
processor twice: before the initialization and after. By default, the object is passed
through with no change. By coding a custom post processor, we can override either
stage, and apply any changes we wish. This can include altering the object itself, or
substituting a different object.
class RemoteService(ObjectPostProcessor):
def post_process_after_initialization(self, obj, obj_name):
if obj_name.endswith(“Service”):
return PyroServiceExporter(service=obj,
service_name=obj_name,
service_port=9000)
else:
return obj
This post processor looks at an object’s name, and if its name ends with Service,
returns a proxy that exports the object as a Pyro service, using the object’s name as
part of the URL. Otherwise, it simply returns the object.
This example shows how we can easily develop a convention-over-configuration
client-server mechanism, simply by using Spring Python’s IoC container and some
custom post processors.
Context aware objects
We can define classes that get a copy of the ApplicationContext injected into the
attribute app_context by extending ApplicationContextAware.
This is only recommended for objects that need to manipulate the context
in some fashion. It is not a good practice to use this hook to simply fetch
objects, because it ties our code directly to the container.
Instead, use the principles of Dependency Injection as shown earlier in this chapter.
Spring Framework Articles
- Spring Framework Articles
- Introduction to Spring MVC Web Framework – Web Tier
- Integrating Spring Framework with Hibernate ORM Framework
- Introduction to Spring Web Framework
- Introduction to Spring’s Aspect Oriented Programming(AOP)
- Introduction to Spring Web Services






September 8, 2010
Spring Framework