Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

So, I'm starting a brand-new project in Java, and am considering using Spring. Why am I considering Spring? Because lots of people tell me I should use Spring! Seriously, any time I've tried to get people to explain what exactly Spring is or what it does, they can never give me a straight answer. I've checked the intros on the SpringSource site, and they're either really complicated or really tutorial-focused, and none of them give me a good idea of why I should be using it, or how it will make my life easier. Sometimes people throw around the term "dependency injection", which just confuses me even more, because I think I have a different understanding of what that term means.

Anyway, here's a little about my background and my app :

Been developing in Java for a while, doing back-end web development. Yes, I do a ton of unit testing. To facilitate this, 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. The one that uses instance variables calls the other one, supplying the instance variables. When it comes time to unit test, I use Mockito to mock up the objects and then make calls to the method that doesn't use instance variables. This is what I've always understood "dependency injection" to be.

My app is pretty simple, from a CS perspective. Small project, 1-2 developers to start with. Mostly CRUD-type operations with a a bunch of search thrown in. Basically a bunch of RESTful web services, plus a web front-end and then eventually some mobile clients. I'm thinking of doing the front-end in straight HTML/CSS/JS/JQuery, so no real plans to use JSP. Using Hibernate as an ORM, and Jersey to implement the webservices.

I've already started coding, and am really eager to get a demo out there that I can shop around and see if anyone wants to invest. So obviously time is of the essence. I understand Spring has quite the learning curve, plus it looks like it necessitates a whole bunch of XML configuration, which I typically try to avoid like the plague. But if it can make my life easier and (especially) if make it can make development and testing faster, I'm willing to bite the bullet and learn Spring.

So please. Educate me. Should I use Spring? Why or why not?

share|improve this question

closed as not constructive by gnat, maple_shaft Jun 15 '12 at 13:03

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.If this question can be reworded to fit the rules in the help center, please edit the question.

13  
Excellent question! +1 –  Mahmoud Hossam Jul 13 '11 at 21:10
2  
I think you really need to try it out for a while for yourself to see if you like it and if its suitable for your project. Personally I hate it. –  Richard Jul 13 '11 at 22:18
1  
While you can use XML or annotations; keep in mind that Spring takes a convention over configuration mentality. It's not necessarily a checklist of items you have to address. –  Aaron McIver Jul 13 '11 at 22:23
5  
While it's true that this question is rather broad, I think it should remain open. I read it as "What benefits does Spring offer for a medium-sized project?", and that's a good question. –  sleske Oct 21 '12 at 9:32
1  
I highly recommend reading my favorite technical book: Spring in Action, Third Edition by Craig Walls. It's a great read and will change the way you program. –  alfredaday Mar 19 at 2:06

6 Answers 6

up vote 29 down vote accepted

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 guageAmount 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.

share|improve this answer
    
I assume that you'd put "SomeWrench" into the setWrench() method, not "SomeHammer", right? –  Zoot Sep 25 '13 at 18:34
    
@Zoot Thanks, fixed. –  Darien Sep 26 '13 at 6:56
    
No problem. I was just making sure I understood the concept. –  Zoot Sep 26 '13 at 16:32

First, what is dependency injection?

Simple. You have a class, it has a private field (set to null) and you declare a public setter that provides the value for that field. In other words, the dependency of the class (the field) is being injected by an external class (via the setter). That's it. Nothing magical.

Second, Spring can be used without XML (or very little)

If you dive in with Spring 3.0.5.GA or higher then you can use the dependency injection support from JDK6+. This means that you can wire up dependencies using the @Component and @Resource annotations.

Why use Spring at all?

Obviously, dependency injection promotes very easy unit testing since all your classes have setters for the important dependencies and these can be easily mocked using your favourite mocking framework to provide the required behaviour.

That aside, Spring also provides a lot of templates which act as base classes to make using the JEE standard technologies a breeze to work with. For example, the JdbcTemplate works well with JDBC, the JpaTemplate does good things with JPA, JmsTemplate makes JMS pretty straightforward. The RestTemplate is simply awesome in it's simplicity. For example:

RestTemplate restTemplate = new RestTemplate();
MyJaxbObject o = restTemplate.getForObject("https://secure.example.org/results/{param1}?param2={param2}",MyJaxbObject.class,"1","2");

and you're done. The parameters are injected and you just need to provide JAXB annotations for MyJaxbObject. That should take no time at all if you've auto-generated them from an XSD using the Maven JAXB plugin. Note that there was no casting going on there, nor was there a need to declare a marshaller. It's all done for you.

I could burble on forever about the wonders of Spring, but maybe the best thing to do is try out a simple code spike where you attempt to wire up a RESTful web service to pump out data from an injected DAO that supports transactions.

share|improve this answer
1  
yeah RestTemplate is pretty awesome. I've got like 100 lines of code that I can throw away and replace with 2-3 lines. –  Kevin Jul 14 '11 at 5:42
3  
To nitpick: Dependency Injection also includes the constructor-based approach. You don't necessarily need to have setters. –  Darien Jul 15 '11 at 18:31

First of all, your understanding of dependency injection is not fundamentally wrong, but quite different from what most people mean when they use the term. What you describe is a rather strange and unconventional way to achieve testability. I'd advise you to move away from it, as other developers will be rather puzzled by that kind of code.

Dependency injection as it's generally understood (and implemented by Spring) means that the dependencies a class has (e.g. a JDBC Datasource) are not fetched by the class itself, but "injected" by a container when the instance is created. So you don't have have two versions of every method that uses the Datasource; instead, you have one dependency injection configuration where the "real" Datasource is injected and one where a mock is injected. Or, if the injection happens via the constructor or a getter, test code can do the injection explicitly.

Second, Spring is not just dependency injection, though that's its core functionality. It also provides declarative transactions, job scheduling, authentication, and a bunch of other functionality (including a fully-fledged MVC web framework) that you may need. There are other frameworks that provide the same functionality, but other than Spring, only Java EE has them all integrated.

share|improve this answer

For why do you want to use Spring, You can read it on http://www.wrox.com/WileyCDA/Section/Why-Use-the-Spring-Framework-.id-130098.html

In summary :

  • J2EE applications tend to contain excessive amounts of "plumbing" code. Many code reviews repeatedly reveal a high proportion of code that doesn't do anything: JNDI lookup code, Transfer Objects, try/catch blocks to acquire and release JDBC resources. . . . Writing and maintaining such plumbing code proves a major drain on resources that should be focused on the application's business domain.

  • Many J2EE applications use a distributed object model where this is inappropriate. This is one of the major causes of excessive code and code duplication. It's also conceptually wrong in many cases; internally distributed applications are more complex than co-located applications, and often much less performant. Of course, if your business requirements dictate a distributed architecture, you need to implement a distributed architecture and accept the trade-off that incurs (and Spring offers features to help in such scenarios). But you shouldn't do so without a compelling reason.

  • The EJB component model is unduly complex. EJB was conceived as a way of reducing complexity when implementing business logic in J2EE applications; it has not succeeded in this aim in practice.

  • EJB is overused. EJB was essentially designed for internally distributed, transactional applications. While nearly all non-trivial applications are transactional, distribution should not be built into the basic component model.

  • Many "J2EE design patterns" are not, in fact, design patterns, but workarounds for technology limitations. Overuse of distribution, and use of complex APIs such as EJB, have generated many questionable design patterns; it's important to examine these critically and look for simpler, more productive, approaches.

  • J2EE applications are hard to unit test. The J2EE APIs, and especially, the EJB component model, were defined before the agile movement took off. Thus their design does not take into account ease of unit testing. Through both APIs and implicit contracts, it is surprisingly difficult to test applications based on EJB and many other J2EE APIs outside an application server. Yet unit testing outside an application server is essential to achieve high test coverage and to reproduce many failure scenarios, such as loss of connectivity to a database. It is also vital to ensuring that tests can be run quickly during the development or maintenance process, minimizing unproductive time waiting for redeployment.

  • Certain J2EE technologies have simply failed. The main offender here is entity beans, which have proven little short of disastrous for productivity and in their constraints on object orientation.

share|improve this answer

It's a framework written in Java with a lot of things included to make your web application functional (e.g. support for internationalization). It also provides a good way to structure your application into layers. Use it, it will save you a lot of time in the long run.

A good book to learn about Spring is: Expert Spring MVC and Web Flow

share|improve this answer

Used to be we wrote simple, efficient, fast applications and web services using just core Java, Servlets and JSP, html and xml, JDBC API. It was good enough; JUnit was a good tool to test. We rested easy that our code worked.

Hibernate came along to simplify SQL and enable true mapping of Database tables with Java objects, allowing hierarchical relationships to be reflected in the Object Relations Mapping or ORM as we call it. I loved it. Especially that we did not have to map the ResultSet back into a Java object or data type.

Struts came along to add the Model View Controller pattern to our Web apps, it was good.

EJBs were a huge overhead and pain and annotations made code look like chicken scratch and now Spring got sprung on us innocent folks. It just seems overdoing to me.

For example we now package our simple jdbc url, user, pass into jdbc.properties first, then into hibernate properties second and then into Spring beans third time!

Versus all that, consider getting a connection where you need it is really as simple as shown below in pure java, which is what we really are doing after going through all that hot air stuff with Spring:

Connection connection = DriverManager.getConnection(url, user, pass);

That is in itself self-explanatory that its a big round about and wrapping round and round to do a simple thing fast and easy with no other big benefits really. It's like wrapping tons and tons of gift paper around a tiny nice gift which is all you really keep anyway.

Another example is a batch update. With Spring it is convoluted involving quite a few classes, interfaces before you can use the JdbcTemplate to do a batch update. With plain jdbc its simply:

Statement statement = connection.createStatement();
statement.addBatch(sqlquery);
statement.executeBatch();

Can't get simpler or faster than that.

I do not support this framework. Sorry. Who on earth wants injections every time they need anything?

share|improve this answer
2  
that code is simple, but where is your transcation handling defined and how do you test it ? Both things are made simpler by spring. Also, you java code is directly tied to a db connection, unless you store connection urls and passwords externally,this is also made simpler by spring. –  NimChimpsky Oct 21 '12 at 13:18

Not the answer you're looking for? Browse other questions tagged or ask your own question.