... Isn't Spring Over?

- -

What is Spring all about?

Spring is commonly described as an Inversion of Control (IOC) or dependency injection container. While I understand what the terms mean, I have the - what would Dave Thomas call it? - novice reaction of.. “So?”

To say Spring does only one thing would be a great injustice. But I have to start in one place, and that’s getting Hibernate and Spring tied together. To do this, a perusal of the documentation and the sample application makes it clear that I’m going to need to work with an ApplicationContext. ApplicationContext is a subclass of BeanFactory, and here’s what the Spring reference manual says that a BeanFactory does:

The BeanFactory provides an advanced configuration mechanism capable of managing beans of any nature, using potentially any kind of storage facility.

Here’s a list of questions I had before my evaluation that were based on this claim, and how Spring ended up.

Q. Can it give me access to many different Hibernate SessionFactory objects at runtime? Because heaven forbid my bosses would sell an entirely separate version of the application to a client…

A. Absolutely. This actually couldn’t be easier.

Q. What about alternate configurations of the same SessionFactory? For example, I need my SessionFactory pointing at a different database in a production environment than where it points during a developmental one.

A. Yes, this is possible. It’s equally as involved as the techniques I’m using with Ant do perform this same task right now, you just have to put the output into a new file. For my own personal implementation, it will actually reduce the number of files I’m having to manage, but I need to do some subtle things with my Spring configuration files first.

Q. What about my actual beans? Certianly my SessionFactory is a bean. What about my POJO’s? Do I have to re-do my Hibernate mappings in Spring format? The sample application would seem to indicate that I do not, but is that just because it’s a lightweight sample?

A. You can use Spring to configure whatever it is that you want. You probably shouldn’t redo your Hibernate mapping files inside, but if you want some pre-fab instantiations of some Hibernate objects, Spring would be the way to go.

OK, So What’s A Bean?

From the reference:

The BeanFactory isn’t limited to just managing beans, it is also able to manage virtually any class you want it to manage. […] (I)t’s possible to have more exotic non-bean-style classes in your BeanFactory.

In other words, clear your mind of what “bean” means in whatever context you are familiar with. “Bean” means any Java class, really. If you’re clever enough, you can use Spring to set up nearly any object you’re interested in. Bean definitions require an implementation class, which is natural enough. One more reason to program to interfaces if you plan on using Spring. Then, you can let it do the dirty work of carrying the right implementation to your classes!

You can describe the methods that need to be called on initialization and destruction of a bean, which is very nice. I can think of a few contexts where that might be useful.

Spring beans can depend on other Spring beans, a concept that will be illustrated in the next Spring post, where you see how to get your hands dirty.

Summary

At this point in my evaluation process, Spring does two things. First, it configures SessionFactory objects very nicely. I don’t have to write any ThreadLocal classes, or re-write the same code over and over when I want to use the same code with different input in different contexts (e.g. inside the container, outside the container, local database, remote database). Second, it will manage the Session objects so I don’t have to. I’ll have to keep an eye out to make sure that this is actually working in a way I understand; as a developer, try not to rely on technologies you don’t understand on some level.

Oh, wait, make it four! I get transaction management and second level caching for free. I’m not kidding. Setting up Hibernate’s transaction manager is an extra three lines of XML, and setting up the cache means copying a JAR file. Spring actually complained when I left out the JAR that enabled the caching ability.

These two—er, four— areas make a big win for me. Also, now I’m in a boat with other people who will be working on the finer points for me, so I can focus on getting my work done. Using open source products puts you on a team, for better or worse. I love teams, so for me, it’s better. Spring does many other things, as well, so they’re ready when I am.

Notes:

I’m still wondering how on Earth Spring is going to handle Session management without knowing about SOFIA! The WebApplicationContext seems like where that magic might happen. Spring is set up and working, however, after about three days of looking at it and working on it off and on. If I do need to understand more about ApplicationContexts to get exactly the behavior I’m looking for, that’s quite all right with me. I’ll share whatever I learn here!

Maybe I was too hard on DAO here. The HibernateClinic class which extends Spring’s HibernateDaoSupport looks exactly like a class I’ve already written to provide many of the same features. If I had written to an interface in the first place, it would be trivial to plug in Spring behind the scenes… for that class, anyway!

A question for the future, since no one actually reads this yet.

Inside the sample petclinic HibernateClinic class, this is about as complex as the code gets:

public List findOwners(String lastName) throws DataAccessException {
    return getHibernateTemplate().find("from Owner owner where owner.lastName like ?", lastName + "%");
}

What about something more complicated? Do your most complicated queries belong in the DAO class/usage pattern? DAO seems to only slightly modify CRUD. Where’s the beef? For now, my persistence service is going to extend HibernateDaoSupport, but will include all the complicated queries.