What does the Spring framework do? Should I use it? Why or why not?
Spring is a framework that helps you to "wire" different components together. It is most useful in cases where you have a lot of components and you might decide to combine them in different ways, or wish to make it easy to swap out one component for another depending on different settings or environments.
This is what I've always understood "dependency injection" to be.
I would suggest a different definition:
"Design your objects so that they rely on an outside force to supply them with what they need, with the expectation that these dependencies are always injected before anybody asks them to start doing their usual jobs."
Compare that against: "Each object is responsible for going out and finding everything and everybody it needs as it starts up."
it looks like it necessitates a whole bunch of XML configuration
Well, most of the XML (or annotation-based) stuff is telling Spring stuff like:
- When someone asks for "HammerStore", I want you to create an instance of
example.HammerStore
and return it. Cache the instance for next time, since there only needs to be one store.
- When someone asks for "SomeHammer", I want you to ask yourself for a "HammerStore", and return the result of the store's
makeHammer()
method. Do not cache this result.
- When someone asks for "SomeWrench", I want you to create an instance of
example.WrenchImpl
, Use the configuration setting gaugeAmount
and put it into the instance's setWrenchSize()
property. Do not cache the result.
- When someone asks for "LocalPlumber", I want to you create an instance of
example.PlumberImpl
. Put the string "Pedro" into its setName()
method, put a "SomeHammer" into its setHammer()
method, and put a "SomeWrench" into its setWrench()
method. Return the result, and cache the result for later since we only need one plumber.
In this way, Spring lets your connect components, label them, control their lifecycles/caching, and alter behavior based on configuration.
To facilitate [testing] I typically make (at least) two versions of a method : one that uses instance variables, and one that only uses variables that are passed in to the method.
That sounds like a lot of overhead for not a lot of benefit for me. Instead, make your instance variables have protected
or package visibility, and locate the unit tests inside the same com.mycompany.whatever
package. That way you can inspect and change the instance variables whenever you want during testing.
With ORM technologies there are many ways to approach this. I think either of the ways you suggest are adequate, but I'll add the performance concern angle.
If you have performance concerns, then I suggest you look at the SQL produced (show_sql) as well as the network traffic via the JDBC driver (use P6Spy or similar) in both versions and see what impact they have.
Best Answer
Back then annotations didn't exist. People hated the XML files, and Java got a horrible reputation because of them. Heck, there was a widely used tool (XDoclet) that generated XML config files from special JavaDoc comments, because maintaining them manually was such a pain!
When annotations were introduced in Java 5, everyone quickly realized that they were for most purposes much, much more maintainable than keeping things that configure intimate details of an application (like service dependencies or DB mappings) in a separate XML files. Realistically, most of the "configuration" is really code as far as changes are concerned, i.e. changes will be made as the application is developed (not while it's deployed) and usually together with changes in the code.
Why is that a problem? Is you build process that horrible? Maybe you should work on that then. But note that both Spring and Hibernate still allow you to use XML configuration, even in combination with annotations. You can even override existing annotations from an XML config file.
The app depends on the framework anyway, otherwise you wouldn't need it. So why pretend otherwise? Besides, many of the annotations are now official Java standards (such as JPA and CDI) and supported by multiple different frameworks.