<!-- --><style type="text/css">@import url(https://www.blogger.com/static/v1/v-css/navbar/3334278262-classic.css); div.b-mobile {display:none;} </style> </head><body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar.g?targetBlogID\x3d7256432\x26blogName\x3dThe+Frustrated+Programmer\x26publishMode\x3dPUBLISH_MODE_BLOGSPOT\x26navbarType\x3dBLACK\x26layoutType\x3dCLASSIC\x26searchRoot\x3dhttp://frustratedprogrammer.blogspot.com/search\x26blogLocale\x3den_US\x26v\x3d2\x26homepageUrl\x3dhttp://frustratedprogrammer.blogspot.com/\x26vt\x3d5012862196962223429', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script>
| Saturday, August 07, 2004

Inversion of Control/Dependency Injection are still big buzz words. Popularity continues to grow for IoC "containers", notably:

In general these reduce couplings between components, letting the IoC container piece your objects together. Struts has some built-in functionality for supporting IoC on data sources, form beans and actions.

Data Sources
A data source can be configured in the struts-config.xml file and accessed through the base Action class's getDataSource() method. A concrete implementation of a datasource can be retrieved through a symbolic name. See Struts - Accessing a database for more information.
The scope of these objects is Global, only one is created per Application.
Every data source is allocated at application startup weather it is used or not.

Form Beans
Form Beans are either custom Java classes (with simple getters and setters for data properties) or generic objects (like Maps or Dyna*Beans). Generic objects can be configured with a list of properties and constraints with default values on those properties, but custom Java classes cannot be configured at all.
The scope of these objects is determined by the Action using the Form Bean. They can be easier Session or Request.
Form Beans are allocated as they are needed.

Actions map a symbolic name to a concrete class. This class is configured with a form bean, a set of mappings and a generic String parameter.
The scope of these objects is Global, only one is created per Application.
Actions are allocated as they are needed and cached until the next use.

The actions are the work-horses in struts. They need to interact with business logic classes, they almost always get a user profile object out of the session. The tight coupling that currently exists in struts actions make them difficult to unit test and reconfigure.

Struts has a fair amount of logic hardcoded in ActionServlet and RequestUtils for performing this Inversion of Control. If this were abstracted out into a plugable helper class, the core struts code could decrease while allowing other projects to maintain the burden of this work.

A new interface called IoCAdaptor could be created, along with three implementations of this interface:

  • StrutsBuiltinIoCAdaptor
  • PicoIoCAdaptor
  • SpringIoCAdaptor

One of these adaptors could be installed into the servlet context by configuring a struts plug-in in the struts-config.xml.

Recently Spring added support for Struts integration. This support came in two forms:

  • Proxy delegates to Spring-managed Action
  • Action has easy access to a Spring context

While this is a nice advance over no integration, I'd still like to see work done at the core of Struts. This would improve the following issues:

  • The IoC code could evolve separately from the struts core.
  • IoC could be supported for Form and DataSources, not just Actions.
  • No need for a special proxy action -- Integration would be more natural.

[Note: This entry was originally written back in December 2003. Webwork and Spring among other UI frameworks fully support dependency injection.]