In my opinion the benefits that IoC / DI bring should be the focus, not the various frameworks that have sprung up (pun intended) to ingrain it into your apps. If you follow the principles of DI, it makes your code amenable to many different frameworks (like the existing “lightweight” containers) or even your own, however minimal it needs to be.
I gave a presentation to the St. Louis Java User’s Group about a year ago on “Designing with Dependency Injection” and focused on the DI aspects without really going into the frameworks too much. You can find links to the presentation in PowerPoint and Keynote here:
In general, I have written a lot of code using DI and interfaces and find that it pulls the configuration and assembly of applications up to the highest level of your apps, making everything below it more testable and less coupled. However, I rarely have more than one implementation of a component interface when I’m first putting an app together (other than testing impls).
If you follow these principles, you can assemble the app in many ways and choose the one that is most suitable. Some different possibilities:
- Code it by hand – just wire the objects together yourself. I always start this way while things are changing fast. With a modern IDE, probably easier than writing a big honking XML config and using Spring.
- Use beanshell (or groovy or …) – using script is like #1 but means you don’t have to recompile to change your assembly, which in some cases is handy (complicated build / deployment environments).
- Use a combination of code and a custom properties/XML file. You don’t really need to decide how to assemble every dependency in your app do you? Of course not! Probably 90% of your app has effectively hard-coded dependencies and you need to swap out key resources (persistence, authentication, whatever). Leverage that to build flexibility only at the points you really need it. By designing with DI, you can also expose the flexibility already in the design at someplace later.
- Use Spring or Pico or Hivemind or another DI framework. In some cases, this may be the right answer (although usually some mixture of 1-3 will work).
I guess my point is that there are a lot of ways (with fewer dependencies and more transparency) to use DI to assemble an app.