Most of you who know me know that I am not a huge fan of Spring. Actually, anything that makes me put business logic in XML makes me crazy (more on that below). Regardless, Spring definitely has had a positive affect on the Java community. The funny thing is that, at least in my opinion, the biggest benefits of Spring is not the framework itself, but the ideas that it promotes. Here are some of the ideas that are now mainstream (or becoming mainstream) due to the success of Spring:
Dependency Injection
The reason I am writing this semi-rant right now is because of some code I found yesterday in a J2EE(EJB) app that I am trying maintain long enough to replace it. Down deep in the bowels of this DAO, there are the following two lines (repeated in almsot every method):
-
home = (BlahBlahEntityHome) ctx.lookup(“ejb.entity.blah.BlahBlahEntity”);
AAAAAAAAH!!! What was the original author of this code thinking?!?!? Well, thats pretty easy to guess: the author was probably thinking about how this code was only going to run in a container, and that getting an InitialContext object is SO simple (when you don’t care about the context) that why not just do it wherever its needed?
Now, guess how I found this code?
I must admit that I’ve done stuff like this in the past, and really it was Spring (and the great book “Better, Faster, Lighter Java” by Bruce Tate) that awoke me to the fact that I am locking myself (and downstream developers) into a prison cell of maintenance hell whenever I do something like that. I think that in this case the J2EE spec made it too easy to do bad things. Why not have a Singleton that you got the Context(s) from?
Anyway, Dependency Injection is a good thing for many reasons.
Spring makes EJBs no longer “necessary” (never were but thats beside the point)
Who needs an EJB when you can have lighter weight Java objects that do not need a container to do their magic? This is a sentiment that I know many people share, and it is spreading. Unfortunately there is a big shadow looming over all of this in the form of EJB3. While EJB3 is certainly better than all of the prior versions combined, multiplied and prettied up for the fair, it is still a heavier weight model than Spring, if for no other reason than you still have the massive production EJB containers. The interesting thing is that this mindset has been around for a _long_ time, and is only now hitting mainstream. I find that kinda sad.
POJOs (or, Back to Better Design Principles)
Another issue I have with J2EE/EJB are the “Blueprints” design patterns. I have been pretty fortunate that in my Java career I have only been witness to a few EJB webapps. These webapps follow the Blueprints, and have at their core a fundemental misunderstanding of code flexibility. There are Business delegates that call DAOs that call business delegates that … ugh I can’t continue. Each method is one or at most two lines of code, calling the next layer in this seemingly endless pile of angel hair spaghetti code. There is little to no flexibility here.
Whereas with Spring, you are once again dealing with Java Objects. Hopefully this distillation back to basics with help developers create a better Object domain. We will see. I think that regardless, it is a good start. Now if only we could get rid of this POJO buzzword….
And now for some not so great things
- Lock in.Same problem with most Java frameworks really, but with Spring it is a little more insideous. For instance, lets say that you only want to use Spring for dependency injection. One of your more enterprising developers (lets call him JoJo) finds the extremely handy JDBC helpers in Spring and starts using them for all of his code. Now the team decides to move to Pico container (for whatever reason) and they remove the Spring jars… uhoh. JoJo’s code no longer worky. We are experiencing this right now on a project I am working on. The lead has decided that we no longer want Spring in the system, but can’t just get rid of it, as it was used heavily in our Data layer. Now, one good thing about Spring is that they have kindof anticipated this, and made the code very modular. You do not need to keep around every Spring jar in the above scenarios, and since you are most likely relying on Depency Injection to make the Spring code work you can just plug the code in directly with out the Spring configuration files. However, it is still an issue.
- Programming in XMLMy biggest dislike of Spring is that it uses XML heavily to manage your configuration. This in effect means you are programming in XML, and if there is one thing I hate, it is using XML as a control structure in my code. Yes yes I know that you can use other things, but pretty much every example I have seen has been XML based. Personally I really really want to start using the Groovy version, as then I have a little more control.
- Thats it
While I have some reservations about it, Spring really is a good framework, and I am impressed by what it can do for you. My dislikes are pretty minor in the grand scheme of a project, but they are issues to take into consideration.
Where Are The Wise Men? » Blog Archive » Outsider Thoughts on Spring | 04-Oct-06 at 8:16 am | Permalink
[...] Matt’s thoughts on Spring came on the same day I just started looking at it. When I mean looking, I literally mean just that. All I did was think “What’s this Spring thing people are asking me about?” So I found this ServerSide article that gives a 1,000 ft overview of Spring. My first thought was one of Matt’s gripes: Programming in XML? No thank Eww. My second: When this abstraction leaks, it probably leaks badly and in insidious ways. [...]
Charles Hudak | 04-Oct-06 at 2:51 pm | Permalink
Spring doesn’t replace EJB’s unless it’s coupled with something like Hibernate. Trust me, Hibernate is no panacea. Contrary to popular belief, Hibernate ‘pojos’ aren’t pojos at all and anyone that tells you that is selling you snake oil.
Honestly, I preferred EJB’s to Hibernate. At least I knew what I was getting. Session management in Hibernate is horrible, especially when you have component libraries that are shared among several projects.
At my last company, we created autogenerated our entire EJB persistence layer from the database schema with the push of a button. There was (and is) absolutely no need to write a single line of EJB Entity Bean code in the entire application. Session Beans were used to define transactional and unit of work boundaries.
Matt | 04-Oct-06 at 4:49 pm | Permalink
I agree that Hibernate is not a panacea, and that the “POJO” that is typically used with Hibernate (ie JavaBean) is definitely NOT the best way to go. However, that has nothing to do with Spring being better than EJB.
I am happy that you were so successful with EJBs on your last project… I personally have not seen (or heard of until now) that type of success with EJB. I am impressed that you did not run into performance issues, as that is a very typical outcome for the EJB Entity Bean solution.
Charles Hudak | 04-Oct-06 at 5:27 pm | Permalink
With the EJB local interface, you eliminate much of the performance overhead of EJB. Local interface method calls are implemented using something analagous to local rpc and so you don’t incur the serialization and network overhead of every call on the bean. Since you should rarely, if ever, expose your entity beans directly to a remote client, virtually all of your entity bean calls are going to be inter-container so you probably should be using the local interface anyways(this is moot with many of the current EJB containers since they will even optimize remote bean invocations with co-located beans).
Using the value object pattern (which is, after all, what you are getting with hibernate POJO’s), all the client code ever sees is a vanilla java bean object. It’s only interaction with the container is via a business delegate (to hide the session beans from direct access of the client). YOu really don’t even need the business delegate–it simply provides the client an abstraction layer from your business logic and persistence implementation. This would allow you to replace session beans with hibernate or direct jdbc access and the client code would never need to change.
Most performance problems are implementation issues, not technology issues. Even a ferrari can seem slow in the hands of a poor driver.
Spring provides a number of similar benefits to EJB deployment descriptors–namely the ability to define component interactions declaratively at deploy time rather than at compile time. I’m also a big fan of DI as it makes testing MUCH easier since you can stub or mock out services that get in the way of testing. I used quite a bit of Spring IN ADDITION to my EJB’s.