I've read Rod's book and a very interesting read it is to: highly recommended. If had to pick out the top issues Rod has with EJBs I think it's that they're hard to (unit) test and are "less than Java": principally because they disallow inheritance (some vendor specific kludges aside) and prevent thread managemenet.
And yet it seems two out of three charges (and an additional one) can also be made against the very heart of Spring: the configuration XML file.
1. How do you unit test an XML configuration file?
2. Assuming I could unit test it, how would I unit test a J2EE dependent configuration without deploying it? (I can't see anyway to mock elements in an XML file!).
3. If the configuration XML file were a Java class I think most people would have a hard time taking the designer seriously: talk about overloaded with responsibility!
4. The configuration file completely lacks any support for genuine modularisation. All the simple import model does is split one physically large file into many parts. Logically it's still one entity with no enforcable boundaries: it's like defining a bunch of classes and making every single attribute and operation, whether internal or not, publicly visible.
5. No compile time checking. With Java I get immediate feedback when I compile a class telling me that there is no attribute called foo or that operation bar isn't visible (with a decent IDE I get that feedback without even compiling). With Spring and the configuration file I only find out that I have two beans named fooBean and barBean doesn't have a property called wibble after I've compiled, deployed and then run my application.
Don't get me wrong: I like the ideas behind Spring: dependency injection and aop proxying are certainly steps forward I just wonder whether it's actually as usefully broadly applicable as it's being sold. (As an aside: I think Inversion of Control is a poor name).
As a replacement for Singletons: yes I can go for that. As a way to load time configure the application: eg configuring an Action with a Strategy where that flexibility is a *requirement*: Yes. As a way of reducing (or eliminating) the application's dependencies on hard to mock resources/environments (ie J2EE): definately.
And of course it's less of an issue in areas where you already have impossible to unit test configurations.
But I wonder if the usefulness of Spring with J2SE applications is much more limited. J2SE applications don't have the inherent difficult-to-testability that Spring addresses: you don't need to deploy it anywhere before running it and, of course, J2SE doesn't suffer from being "less than Java" in the way that EJBs do.
For example, probably the biggest improvement we've made as a result of incorporating Spring into our J2SE applications was in switching from using template methods to using strategys to configure Actions. As a result we've reduce my code count in that area by about half: which is great! But whilst that was triggered by my exposure to Spring (or more specifically Rod's book) it in no way depends on Spring.
So the conclusions I've come to about Spring are:
1. It's maximum benefit comes in building J2EE applications. Both in making them easier to unit test and breaking the tight coupling between application and the J2EE server. And this is no small thing! The major downside to Spring: the untestable configuration xml isn't such an issue in J2EE which is already awash with such beasts, so replace one with another <shrug>: at least the problem's no bigger.
2. For J2SE the benefits are much smaller simply because the same problems that exist with J2EE simply do not exist in J2SE. And adding in an untestable monolithic configuration file is a definite net change for the worse. In J2SE Spring is probably most useful for directly replacing existing Singletons (by run time configuring the classes that need a resource with that resource, rather than having them call a global object to lookup the resource) and as a result keeping the configuration xml as small as possible.