In short, I do believe that Spring framework forced you for a long time to use a subset of Java, a subset of frameworks you use, and has been implicitly very intrusive on all the frameworks that support it. It constrains innovation and limit choices. And more!
Unfortunately I would not be able to list in this post all the arguments I have because of lack of time. I would rather provide few examples that shows why the Spring culture is unacceptable for me. Of course you can reply saying that Spring will support this, or is supporting this starting with version x. Well I am afraid I don’t care. Spring existed for a long time now, and my judgement is based on a long history. Besides what I am targeting is the culture of the framework.
First of all, if you want to use Spring Beans you need to believe in magic. Don’t agree?
class MyServiceClass {
private IMyDao myDao;
// Other stuff goes here.
}
this field "myDao" is never initialized, not by any constructor and it is private. But if you believe in magic, then you can use it. Because you know what? There is a wizard config file that you can find if you search enough in your project that will "inject" it. What?!!
First of all this solution violates member visibility rules in Java. But ignoring that, this results in a practice or a habit to ignore a never initialized field believing in magic! A framework that offers and advocates such a violating is not worth even trying IMHO!
Now the suggested solution is to write a setter for this field that then will be used by Spring, but this changes nothing as anyway you will either make it public (allowing any public user of your API to set you DAO!) or put it back private and back to the never initialized field! Did I mention "final" yet? :)
Spring claims that it is not intrusive. What? Now imagine that you remove Spring from your dependencies list, your application is no more useful and you suddenly get null pointer exception everywhere my friend! Who will inject the private field? or a private setter? This claim is ridiculous!
Now did it happen to you to forget to declare or mistype your beans in your config? What happens? Runtime exception! What? I thought Java applications are statically typed!
Now I can hear you, use annotations! Annotations solves your problem! Well I am afraid not. Annotations like @Required or @AutoWired is just like begging the user not delete the field or property, and it is not mandatory and not forced by any checker. Remember, I am talking culture here…
Now if you are a defender of injection using constructors, then I believe you got something right and most probably you reject most of the hacks I mentioned above (Including setters based injection, private field injection, aspects based injection (in short 80% of what Spring Beans mainly offers and actually does)). But then, you turned anyway your architecture dependency into dynamic, never checked and its composition specified in desperate XML files! Think of code navigability, and software flow and dependencies that you can not trace without the help of a debugger using this approach.
Oh, what about JavaConfig. Well yeah, I do not need Spring to do that! "new", you remember the keyword "new"? yeah OOP, new, instances. That is Java programming. Trust me "new" is no evil, and guess what, you need no dependencies to any framework to resolve your dependencies in a statically checked, navigable, readable, simple, clear, elegant, concise, safe and beautiful way!
Last thing for now, you need to learn Spring-FU to use any, any framework that wasn’t designed specifically for use with Spring and yet you may not succeed (though framework designers are forced to be distracted by Spring design when defining their architecture, for examples see Restlet and Jersey) ! That reminds me of something…
YAGNI!


We know Spring beans is a bit tricky sometimes (noclassdeffound exceptions…) and if you can’t bear it, you can use constructors to do nearly the same.
But in an IT services company, don’t you think we need an easy pattern to define the services/DAOs/etc dependancies or not ?
Application development need many pattern in order to be standardized !! If not, developers use 10000 different ways to do the same thing… with spring, you can forgot this problem… and think about your new (spring) problems…
I think using Spring beans to manage IOC is a good way of dev-life !
Sorry for my frenchy english…
Is it your christmas present to the springsource group ???
Comment by Cyril Lakech — December 30, 2008 @ 5:59 pm
Hi Cyril,
I guess enterprise needs simplicity! I guess any Java developer is aware of what constructors are, and is capable of using them to resolve dependencies. On the other hand I can’t see how Spring solves the problem when there is a lack of discipline! In Spring itself there are several ways of doing the same injection thing. You know why Ruby wins? Because of its simplicity and its frameworks that exploit its power, in contrast with Java and its frameworks that constrain its power!
Comment by Sadache — December 30, 2008 @ 6:15 pm
And if standardized patterns include leaving a private field with null value and then calling on it, and having setters that are either private and not used or public and accessible by anyone then I do not want these patterns for my architecture!
Comment by Sadache — December 30, 2008 @ 6:33 pm
Spring is an IOC framework. An IOC architecture by definition means that your objects get their required dependencies injected. If the framework doesn’t do this, it’s not an IOC framework.
Now, if you don’t like IOC, that is a matter of preference. I find that IOC makes for a much cleaner implementation since the wiring is all centrally located. Much less clutter and boilerplate.
But of course, like all other OO concepts added after the fact, this doesn’t come for free. You no longer have the static typing that you would have with regular Java, but so what? It’s not that hard for a competent software engineer to keep the dependencies in sync, and it’s not that hard to find dependency faults with proper test code. If you have decent test coverage, a wiring fault will be discovered immediately.
Of course, you COULD have full compile-time type checking if Java supported IOC natively.
But it doesn’t.
And so we play language tricks to make it do IOC.
It’s not perfect (and nothing ever is), but it’s a damn sight better than non-IOC on big projects.
Comment by Wolter — December 30, 2008 @ 7:54 pm
I mostly agree with you are saying about the dependency injection. I think using constructor dependency injection is the right way to go a shame the names of the arguments are lost in compilation and thus not available for auto completion in the application context. But I think you are not completely fair to Spring, it offers more than just dependency injection. Things like transaction demarcation for jdbc/jpa for instance. Spring can only do its “magic” because of dependency injection.
Comment by johan — December 30, 2008 @ 9:00 pm
@Johan
You are right. I tried to be careful about mentioning only Spring IoD but seems not enough. JDBC is something that Spring does well (except the fact that I would have prefered it to keep checked exceptions but that is another story).
Comment by Sadache — December 30, 2008 @ 9:30 pm
1. no more crummy factory hacks featuring double synchronization and other broken paradigms of singletons
2. no more static static static everywhere for utility classes
3. no more xml configuration (I’m a firm believer in Autowired)
4. no more insane object hierarchies, encouraging composition over inheritance
5. a super easy, documented configuration format for those which need to be externalized
i could go on but i’m lazy.
Comment by Ivan — December 31, 2008 @ 1:39 am
@Ivan Spring encourages composition over imheritence? you should be kidding! Spring encourages one thing: Procedural programming with singleton classes wrapping procedures! This is not composition but rather module mapping… OOP is about objects, instances you know… Not singletons!
Comment by Sadache — December 31, 2008 @ 3:35 am
Here is a debate about DI from last year http://www.infoq.com/news/2007/12/does-di-pay-off
Comment by Sadache — December 31, 2008 @ 9:43 am
for navigating through code you always need some kind of tool, IDE or whatever. try navigating your code with only a simple editor… so, if you want navigability when using Spring IOC, you should do the same: use a tool that understands Spring IOC. one of your problems solved …
Comment by dizzy — December 31, 2008 @ 10:24 am
You are wrong and mistaken in so many things but I can’t explain because of lack of time …
Comment by oh boy — December 31, 2008 @ 10:27 am
You need to understand that the fundamentals of Spring were designed years ago when the EJB times were around.
Spring was less intrusive, because it did not enforce you to subclass/implement any framework classes/interfaces. Your business logic was clean and simple Java classes which did not require strange imports from your framework. Besides that your classes could be run without any container (ejb-app-server or anything like that). That is what is meant by less intrusive.
Now Dependency Injection is deadly necessary to structure Java code in a way that makes the application testable. Mixing the “new” Operator with your business logic is death to testability in Java, since you can no longer exchange the instantiated object with a stub/mock/spy. There is no other way to write testable java code, but to use Dependency Injection, because all the dependencies must be there at compile-time. It is a special way of structuring an application for testability. Spring pioneered this way of structuring enterprise java applications a long time ago with the instruments that were avaiable at that time (there were no generics back then, they had to go with external config, which is btw nice executable documentation).
Of course, Constructor Injection is better, but then you had to get the order of elements correct in your xml file. In a sole DI-Framework like Guice, there is no need for any external configuration or Factories. Your dependecies are inferred and instantiated by Guice.
Comment by Sakuraba — December 31, 2008 @ 12:52 pm
You are absolutely correct. IMO, IOC/DI is in reality an anti-pattern!
Isolating code under test from its dependencies is a problem to be solved in test code only, and should not require changes to production code. There exist tools for this, such as JMockit (which I created precisely because I could not accept the idea of having to change perfectly good production code for the sake of unit testing it) and TypeMock in the .NET world.
Another thing is that many developers seem to love the idea of having separate abstractions/interfaces for everything, when in fact those abstractions end up having a single implementation. And DI provides incentive to such over-engineering impulses. I prefer to simply use the “new” operator, and avoid other anti-patterns such as DAOs and factories. Those rare situations which require a separate interface do not justify introducing complex frameworks such as Spring or Guice, IMO.
An evil consequence of using DI is that you end up with lots of stateless service objects, which could instead be stateful objects, properly instantiated in client code with context specific data, which ironically is a more OO solution. Java does not support inner methods, so the only way to avoid having lots of private methods with several parameters each is to use instance fields. But you normally can’t do that if the class has to be stateless.
I would recommend people read the official articles on the DIP and OCP “principles”; not because I agree with them, quite the contrary. I think maybe if developers understand the real motivations (hint: C++ language issues) behind some very questionable and old ideas, they may start questioning their modern counterparts.
Comment by Rogério Liesenfeld — December 31, 2008 @ 1:03 pm
I wouldn’t say that the “new” keyword is evil, but in terms of heavyweight , collaborating classes, I’d say it would be better to avoid using it, and that’s what Spring advocates as an IoC container.
Sure, it is a matter of preference, but referring to collaborating classes through an interface instead through the “new” keyword offers many benefits, the most important being loosely coupled classes, and easier unit testing, and as another side benefit, refactoring w/o fear. Who doesn’t want that?
In your example, it will be extremely hard to unit test the class “MyServiceClass” if the DAO is not injected, but rather instantiated with the new keyword. Instead, you will be forced to set up a test data base, including teardown/setup, and the test will be slow. Using an IoC container such as Spring (or maybe PicoContainer if you really don’t like Spring) will allow you to keep the service class loosely coupled to the DAO, and allow for quick, iterative development with extremely fast feedback from your unit tests.
Comment by Ken — December 31, 2008 @ 1:22 pm
@Ken , Sakuraba
Loose coupling is a fruit of good design and architecture, and Spring, DI or IoC have nothing to do with that. For testability and loose coupling I can have two constructors, one parameterless that specifies “DAO” dependencies for production code, and another with parameters to be used when testing. Did that look like a lot of work?
I really respect the marketing work done by Spring to make you believe so much that it is behind loose coupling and testability!
People forgot the difference between a class and an instance …
Comment by Sadache — December 31, 2008 @ 2:56 pm
@Rogério
You nailed it on the head! Yet other important arguments I did not include, thank you!
Comment by Sadache — December 31, 2008 @ 3:15 pm
What you criticize is really Ioc, not Spring beans. I think that Ioc, well used, is a very good pattern. I don’t know if Adwords would have been possible without Guice. Now, you don’t need to use any framework to do Ioc. You can also use Spring or Guice very efficently assuming you don’t use a JavaBean model.
@Rogério, I agree that Ioc shouldn’t be used in the first place just to make your tests easier to write. However, even with the best mock framework, I’ve never seen tests that are expressive and maintenable. On the other side, Ioc gives me maintenable tests. So I choose Ioc, having no better tool available.
Comment by David — December 31, 2008 @ 4:38 pm
I am addressing both. Spring encourages anti patterns and poor Java code for doing IoC. IoC in its turn is not necessary and I consider as a code smell and as Rogério said an anti-pattern.
I guess this is an over exaggerated argument, can you explain more or point me to links?
A lot of cool applications has been written with languages with no IoC. If I am not mistaken Reddit is written in Lisp ))))))
Comment by Sadache — December 31, 2008 @ 4:54 pm
> I am addressing both. Spring encourages anti patterns for doing IoC. IoC in its turn is not necessary and I consider as a code smell and as Rogério said an anti-pattern.
IOC, like any other pattern, is situational.
For example, I work in a bank. I’ve built an enterprise application that is now closing in on 10MB of java code. It’s a kind of clearing house for present, future dated, and periodical transactions, a data entry system, report generator, as well as a gateway to the various legacy applications written in COBOL.
It needs to get data from all sorts of locations, be it property files, XML data, structured record files from a COBOL process, databases, SOAP, you name it. And the applications it needs to interact with are constantly changing.
Parts of it need to be accessed via a web interface, and others through interfaces that emulate the systems that it has replaced.
So what to do? So many of the services are used by so many of the subsystems that anything BUT an IOC pattern would be absolute chaos.
I don’t program by rules; I use rules of thumb, but take an intelligent look at what actually needs to be achieved. I don’t go exclusively with an interface/implementation pattern unless it’s highly likely that I’ll have to move to a new implementation. For those things less likely to require such a pattern, I do it with a straight implementation. If it turns out that I need multiple implementations later on, I can refactor to an interface design when it’s actually needed. This is the basic idea behind agile development. You don’t need to handle all possibilities up front, but you DO need supple code if you ever hope to refactor, and a big part of that involves keeping the coupling level relatively low.
So far, the ONLY objects that I have religiously used the interface/implementation pattern on are the data objects, because the source of the data often changes as we upgrade other systems. The most common path is from a COBOL routine to reading a file, to getting it from a database. And a few times we’ve needed all three at once with a software switch because of scheduling conflicts.
It’s not IOC that’s the antipattern; it’s the clueless developers using it improperly who make the antipattern. Remember all the hooplah a few years back about how new programming languages were going to be written in XML? This is the same kind of thing.
OOP is about relationships. The patterns themselves are tools to achieve the desired relationship. Get the relationship wrong, and you’ll get the implementation wrong.
Comment by Wolter — December 31, 2008 @ 5:23 pm
@Sadache,
No one says you have to design everything via Spring-aka not *every* class has to be Spring enabled.
For my applications I design subsystems with a healthy mixture of OOP and design patterns etc. When it comes time to integrate that new feature into a larger application, Spring is there to help me do that without worrying about the subsystems lifecycle- Spring already takes care of all that.
Comment by Ivan — December 31, 2008 @ 5:50 pm
I agree with you. Spring sucks. Annotations sucks.
Comment by MFR — December 31, 2008 @ 11:46 pm
Thank you Sadache and also Rogério Liesenfeld for your comments. I was beginning to feel like I was the only one with these thoughts.
Comment by anonymous — January 1, 2009 @ 5:34 am
@Ivan
I am glad you are talking about a healthy mixture of OOP and design patterns. My issue is that I can do the “integration into a larger application” simply and without the need to Spring. Spring takes care of nothing for me as behind the scenes all what it does is either guarantee one instance (Singleton is often a bad practice and maybe a code smell in an OOP system) or call instantiation. No big words, no design no rocket science there. That is why, and in most enterprise application architectures I’ve been involved in, I was happy and proud not to add this huge dependency and to do the simple way!
Comment by Sadache — January 1, 2009 @ 10:41 am
@Wolter
Again, this is not IoC, this is Strategy Pattern you are talking about…
OOP is about relationships between instances not between classes. Spring emphasizes classes and ignores so much instances. I know you can use “prototype” but you do it in a much of a static way (because Spring configuration files are static).
I agree partially with you. Yet Spring did introduce the magic of private never assigned fields! This is one of many anti-patterns and code smells Spring introduced in Java code!
Comment by Sadache — January 1, 2009 @ 11:08 am
> OOP is about relationships between instances not between classes. Spring emphasizes classes and ignores so much instances. I know you can use “prototype†but you do it in a much of a static way (because Spring configuration files are static).
I’m not quite sure I follow here… Some things simply are class relationships. For example:
bean logger:
- property logDao, ref logDao
- property currentUser, ref currentUserProxy
- property userDao, ref userDao
- property properties, ref primaryProperties
bean logPurger:
- property logDao, ref logDao
- property properties, ref primaryProperties
In this case, it makes sense to have one logger and one log purger. So many of these objects have an instantiation lifetime AND relationship lifetime that is equivalent to the running time of the program, so singleton makes sense.
The current user IS dynamic, but since the user data could reside in different dynamic data pools depending on how you access the system (via web, command line, TCP/IP link with some custom credentials and session mechanism and such, I ended up making this a proxy class that seeks out where the true data is stored.
In this case, I’m not sure how it could have been done differently. The current user has a MUCH shorter lifespan than the business objects + a few services that need to know about it, so it would make sense to have a long-lived proxy service that does the legwork of finding the information about the shorter-lived data.
On the web interface side, you have a LOT of short lived objects that present the view to the user. These objects make use of business and services, but are short-lived themselves:
operations job editor (not singleton):
- property localization, ref masterLocalization (references a singleton)
- property operationsJobBusiness, ref operationsJobBusiness (references a singleton)
- property log, ref logger (references a singleton)
- property table, ref operationsJobTable (not singleton)
- property editRequestor, ref operationsJobEditRequestor (not singleton)
Any time the UI requests the job editor screen, it gets a new instance. It makes use of some complex UI components which are built on-the-fly and added via spring. When the user leaves the screen, the editor and any non-singletons it uses are dereferenced.
I chose not to autowire in this project for fear that it would make for some very difficult-to-find null references, but I’m starting to think that perhaps a hybrid approach would work well: autowiring for long-lived singleton references, specific wiring for short-lived stuff.
Now, doing all this in an xml file is definitely not the nicest way to do things, which is why I point to the deficiencies in the Java language, rather than the concept itself. Direct language support for managing dynamic relationships and configuration without loads of boilerplate would be very nice, indeed.
Comment by Wolter — January 1, 2009 @ 5:00 pm
Spring, despite its claim that it is a lightweight container, is too big, too cumbersome and overly complex. In short, it sucks. Probably as much as Hibernate does. And why is this the case? The Java language (and I am a long-time Java programmer), by its very nature, ultimately leads to this kind of complexity, which is almost as bad as the obscurity that comes with template programming in C++. Yuck.
Comment by Thomas J Clancy — January 1, 2009 @ 8:12 pm
Quoting out of order—
>First of all, if you want to use Spring Beans you need to believe in magic. Don’t agree?
1) 100% avoidable with constructor injection.
>Now did it happen to you to forget to declare or mistype your beans in your config? What happens? Runtime exception! What? I thought Java applications are statically typed!
2) A huge problem with Spring XML, but not with DI in general. Guice, as others have pointed out, has no such problem, nor does Spring JavaConfig.
>Loose coupling is a fruit of good design and architecture, and Spring, DI or IoC have nothing to do with that. For testability and loose coupling I can have two constructors, one parameterless that specifies “DAO†dependencies for production code, and another with parameters to be used when testing. Did that look like a lot of work?
No, it is not a lot of work, for one class. Dozens, hundreds, or thousands of classes, yes, that is too much work and a far worse smell than (constructor-injected) DI. Other users of your library either have to have access to your source (or you have to write very explicit javadocs) to know in what contexts to use what constructors. Plus, whereas Spring “magic” might lead to runtime NPE (again, 100% avoidable with constructor injection), in your example you can also create situations where the use of the wrong constructor might actually succeed, altering production context or data, when it is not intended. That is far worse, and far more likely to happen unless you have extremely tight control over every coder in your team. Externalizing these things in properties files? Congratulations, you may not want to call it that, but properties files are conceptually similar to DI. (As you say, DI is not rocket science — it is just handing an object its dependencies.) And back to testing, this way also presents you much more work to perform integration testing of several classes in concert, since you have to construct the proper constructor chain for every object in the test, every time, for every such test. If DI is a smell, this is a fetid stench.
>Now I can hear you, use annotations! Annotations solves your problem! Well I am afraid not. Annotations like @Required or @AutoWired is just like begging the user not delete the field or property, and it is not mandatory and not forced by any checker. Remember, I am talking culture here…
Yes, because multiple situational constructors is mandatory and explicitly type checked, and does not require any extra conceptual or cultural baggage on the part of users or developers. :) In addition to the above, there is also no way for a new developer on your team to know which (and how) properties are set other than to walk the constructor chain of each dependency. That sounds like a recipe for failure for any but the smallest, most tightly controlled culture teams. I will not take Spring XML given the choice, but if I had to choose between ugly XML and classes with @Required that fail only at runtime at startup, versus your magic constructors that can succeed long enough to cause damage, I will take the ugly XML every time. Sorry, but your solution solves one problem by creating a far worse one.
>I guess this is an over exaggerated argument, can you explain more or point me to links?
It takes about 30 seconds to find the Guice project site, which contains numerous references. Most of the Bob Lee’s explanation about Guice’s role in AdWords and at Google are in the linked videos, so it is hard to quote here. Here is a summary quote, from the Spring comparison page:
http://code.google.com/p/google-guice/wiki/SpringComparison
“Guice is anything but a rehash of Spring. Guice was born purely out of use cases from one of Google’s biggest (in every way) applications: AdWords. We sat down and asked ourselves, how do we really want to build this application going forward? Guice enables our answer. ”
>OOP is about relationships between instances not between classes. Spring emphasizes classes and ignores so much instances. I know you can use “prototype†but you do it in a much of a static way (because Spring configuration files are static).
Spring manages relationships between instances, and, while you are correct that the most common Spring case is managing single instances of service classes (effectively, though not literally, singletons), Spring has had more options than “singleton”/prototype for a couple of years now. It ships with support for request, session, and global session, and provides you the ability to define your own custom scopes as required.
http://static.springframework.org/spring/docs/2.0.x/reference/beans.html#beans-factory-scopes
Don’t get me wrong — Spring is heavy, and not appropriate for many places where people blindly plug it in. I agree that despite claims of it being “non-intrusive,” it does encourage a certain style in your code, which is intrusion, in a way. There are oodles of projects where I would not use Spring, and some where I would not use DI. But this blog entry sets up strawmen arguments using outdated information and presents even worse solutions.
Comment by gl — January 2, 2009 @ 5:30 am
@gl
You do not need to make the unit tests targeted constructors public, just keep them package private.
Inside the package itself, well that is a less important concern, and indeed you can either add JavaDoc (which is a good practice) or use annotations to generate warnings.
Constructors allow you to use final fields which guaranteed no mutation to your objects’ state when necessary (IMO always).
You do not need to follow constructors chain. At each level of composition a parameterless constructor sets its dependencies for production. So for instance if you want to know what is your EmployerSalleryCalculator depending on, well you see the parameterless constructor. Of course now you can ask yourself further questions about the composition of its components, but you know again where to find it. Each concrete class is responsible for specifying its dependencies. Isn’t that the single responsibility and separation of concerns principle? I am afraid Spring does not follow the principle…
And by the way, you have never had to walk dependencies chains in different Spring configurations files? I am sure constructors are more navigable. Everyone got ctrl+click!
I am afraid I didn’t get your argument. You mean you can not change at runtime what is @AutoWrapp ed? When as I told you can control the visibility of your constructors and expose only parameterless ones.
I am not doubting the success of projects based on Guice or DI in general. I am just sure there are a lot a lot of projects that succeed with no DI.
From your argument I could understand that you are for Constructor Injection which is good. But then you try to show that constructors are bad (where as I described above, I disagree with you). So what are you for?
BTW: I like what Guice states
Wherever possible, use constructor injection to create immutable objects. Immutable objects are simple, shareable, and can be composed
Comment by Sadache — January 2, 2009 @ 6:49 pm
@Wolter
Unfortunately I will be mistaken whatever I comment on your example. I know nothing about your business context which I consider essential for any design or architecture.
Again, what you gave as information is about the static structure and not runtime behavior. You know class diagram vs object diagram and sequence diagram.
Comment by Sadache — January 2, 2009 @ 7:24 pm
Thanks for the wonderful post.
I get pimples when exposed to 25klos xml configuration. You love it? Well, you may, but you loose lots of stuff the javacc makes you bleed for.
In my eyes it is a silly idea to use the “simple” frameworks.
Even the sort of – well let me call it interesting – EJB spec seems light weight compared to the weight Spring imposes on me (okay, EJB is for RPC only, however …).
@cyrill: To say it in a nice manner: If your shop has no discipline, it has no discipline. Full Stop. And good luck when checking discipline in 25klos xml configuration!
@cyrill: IOC was discussed long time BEFORE spring, though it was named another way – If I’m right it started out with DIP (http://www.objectmentor.com/resources/articles/dip.pdf). Thanks to Fowler every name changes :-(. You can do IOC with and without containers. Actually try to rewrite your code WITHOUT Spring and you will be surprised, how much easier it is to comperehend, and most probably even shorter in length.
@sadache: It’s the Java “Architects” that love stuff like Spring. Did you know, you do not have to know Java programming to become a “Architect”. Try to talk to them about nice stuff, like constructing your main application by healthy sized apps, ACID and CAP. Nogo. Or try to make them apply (in contrast to only naming) simple design, architecture or documentation rules and they will fail.
@wolter: You are , well, I’d say, not fully correct. Please check the link above (DIP).
@evan: You can do this all with good plain old Java and core Java APIs. Just give it a try. And please compare the 25 klos xml with the size of the additional glue code. The glue code will be shorter.
@dizzy: Well, sort of funny. That sort of answer the same way, whenever I am asked about a weakness: “Well, it isn’t that bad if only …”. Your answer states that it is bad.
@Sakuraba: No, spring was not the first Java IoC framework. I was once forced to use Avalon(http://avalon.apache.org/closed.html) …
####################
THAT SAID: Just give good plain old Java a try. You’ll be surprised, how good it fits.
####################
Thank you for this post.
Regards
John
Comment by johnofanger — January 3, 2009 @ 8:41 pm
@John
I just read the entire article, and I fail to see how I am not correct, unless it is simply a misunderstanding due to the medium being used for idea exchange (As Sadache so astutely pointed out, I have not posted any interaction diagrams in this text-only forum).
What I have found is that in general, using interfaces just to be flexible is a waste of resources and unnecessarily bloats the code. The majority of the code you write for most projects is domain specific, task specific, and is highly unlikely to be reused.
In the event that code IS targeted for reuse, it’s not very hard to abstract an interface (hell, most IDEs can do it with a single click of the mouse!).
What’s more, larger code reuse efforts in the business world involve taking business or data logic and centralizing it via distributed interfaces. This happens after it’s discovered that multiple projects by different teams are doing essentially the same thing, and it’s ALWAYS implemented differently in different projects. You’d be hard pressed to have such intricate control over the designs in your software house that you’d catch these things, unless you became such a micro-manager that all of your developers quit in disgust.
Sticking to concrete classes but using DI for wiring gets you halfway to full code portability while at the same time reducing boilerplate and ugly service finders that shouldn’t be in your unrelated code. Making it fully portable is a simple matter of making an abstraction that matches the common behavior between the existing implementation and the new extra implementation, making a few changes using the many refactoring tools of your IDE, and recompiling. Usually this takes me no more than half an hour.
The article’s complaints about having to at least recompile the Button module don’t apply to dynamically linked languages like Java and C#, so you’re only left with having to change Button if the PUBLIC INTERFACE of Lamp changes, an unlikely scenario indeed, and once again mitigated by refactoring tools.
Use sound design principles that match the circumstances. Only add indirection if you have compelling evidence that you’ll need it in the future and the cost of doing it now will be considerably less. 100% flexible code results in a programming language.
Comment by Wolter — January 4, 2009 @ 4:17 pm
@Wolter comment #19
I’ve seen Spring usage for integration issue within application, whereas this problem should be solve by lightweight integration framework such as Mule, Apache ServiceMix or Apache Camel. I do work also in a bank, we have some Spring usage in our application, but not for integration issue such as Cobol communication as you mentioned.
Have a look at Spring Integration, another interesting framework that’s worth to try and avoid too many technical glue code.
@Sadache : nice post, I think you underestimate the amount of “I love/I hate Spring”. I really appreciate the comments, still interesting.
There’s also another subject that you should have a look : “Do I still need Spring IoC when I write EJB3.1 apps only?” There was a nice presentation at Devoxx 2008, I’ll send you the link by mail.
Comment by Nicolas Martignole — January 6, 2009 @ 11:18 am
Injection is not magic nor a fate.
You can write this :
@Autowired
IFooDao fooDao = DaoFactory.getFooDao(); // or new FooDaoImpl(), or whatever
If the field is injected by Spring, the default value is not set. The opposite is true, too : is Spring doesn’ inject the field, guess what, your program will use the standart, manually initialized value.
By doing so, your programm can run whether Spring is available or not. That’s what I call non-invasiveness !
Comment by Olivier Croisier — March 9, 2009 @ 9:25 pm
“Now did it happen to you to forget to declare or mistype your beans in your config? What happens? Runtime exception! What? I thought Java applications are statically typed!”
If you use Spring to manage your beans, and you do not use an init method or implement InitializingBean for its afterPropertiesSet check, and you get a RuntimeException because of that, then you fail. Period. The error is on you. Don’t blame Spring for your failure. The same would happen if you used “new” and forgot to give an actual reference to your pet constructor.
Comment by MF2002 — March 11, 2009 @ 6:08 pm