December 22, 2014
Hot Topics:

A Quick Introduction to the Spring Python Framework

  • November 9, 2009
  • By Cesar Otero
  • Send Email »
  • More Articles »

Getting Started With Spring Python

In our example, we'll create a program that requires a logger. For whatever reason, we want to use a mock object, that can easily be replaced later. The first step is to define our Spring object, which will be injected at execution time. The original Java Spring uses "Beans", which is really just a POJO or plain old Java object. I suspect that plain old Python objects (POPOs!) probably won't catch on; the equivalent in Spring Python is simply Objects. I'll use the term Spring Object to avoid confusion. Listing 4 shows a Python class for our logger. Note, the file name is Lumber.

  class Logger:
      def getDestination(self):
          return self.destination 
  
      def write(self):
          print "writing to log:", self.msg

Listing 4. Our simple Spring Object, Logger, in module Lumber.

This Spring Object has two properties, Destination and Msg, as well as a write method. Each property has a corresponding get and set method. Different from the Java implementation of Spring, setter's aren't necessary. The Spring Objects are defined in an external XML file, shown in Listing 5.

The XML format is very similar to the Java Spring version. Each object, defined with the <object> tag, has an id, or object name, its deriving class, and the scope. Only two scopes are possible, prototype or singleton. In listing 5 we define an object called logger which is of the class Lumber.Logger. We use the property "destination" with a value of "<CODE>/who/knows/where/loggit.txt</CODE>".

  <?xml version="1.0" encoding="UTF-8"?>
  <objects xmlns="http://www.springframework.org/springpython/schema/objects"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/springpython/schema/objects
   http://springpython.webfactional.com/schema/context/spring-python-context-1.0.xsd">
           
    <object id="logger" class="Lumber.Logger" scope="prototype">
      <property name="destination"     
                value="/who/knows/where/loggit.txt"/>
    </object>
  </objects>

Listing 5. Our XML configuration file, applicationContext.xml, with property destination

Because we're using Python, we can dynamically add properties. Setter's in the Spring Object are not necessary, although, if that's your style of programming feel free to add those methods. Now that we have a Spring Object, and the configuration for it, we can create the sample app, where we'll inject the dependency, Lumber.Logger.

  from springpython.context import ApplicationContext
  from springpython.config import XMLConfig
  
  container = ApplicationContext(XMLConfig("applicationContext.xml"))
  logger = container.get_object("logger")
  
  print "all messages will be logged into ", logger.getDestination()
  
  try:
      print unboundVariableWatchMeBlowUp 
  except:
      logger.msg = "A critical error has occurred of type xyz"
      logger.write() 

Listing 6. The main program. A spring container is created

Using springpython.context.ApplicationContext() we create our container, which will be used to inject the logger defined in the XML configuration file. As you can see from the first print message, logger is indeed the object defined externally, and we can call it's method getDestination(). In our sample application, we log a message after an exception is raised. We add the property msg, with a string value, and then call the method write().

In a real world application, after development of the main program is finished, the simplistic Lumber.Logger class can be replaced with a complete, and sophisticated logging system. For example, that will be able to write data over a network. The only requirements in our sample application is that the new logger have a getDestination() and write() method (Think, design by contract).

Conclusion

I don't believe that DI should be used everywhere all the time, but I think there are advantages to be gained. If you didn't already know, there's a pretty viscous debate going on about whether DI makes any sense in dynamic languages like Python and Ruby. I'll probably get hate mail for writing this article.

Besides that minor point, if you can't wrap your head around the idea of inversion of control, try to look at it from implementation point of view. You have a Python class that will be instantiated by the Spring container. Define your class, create the XML config file with the initial values that you'd like, create a Spring container inside of the dependent component, get the object via the container. Now you can use this object like any other Python object. That's it, really.

References

The Spring Python home page
A great opinion piece on why, and when, you should use Spring Python
Martin Fowler's explanation on Inversion of Control and Dependency Injection
Another article by Martin Fowler on both DI and IoC
A Wikipedia article on DI, mentions some other Python frameworks





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel