views:

908

answers:

10

Possible Duplicates:
What is dependency injection?
What exactly is Spring for?

I want to know What is Spring Framework? Why and when should one use it in Java Enterprise development? The answer would be "A dependency injection framework". All right, what advantages do we have when using dependency injection frameworks? The idea of describing classes with setter values and/or constructor parameters seems strange to me. Why do that? Because we can change the properties without recompiling the project? Is that all what we gain?

Then, what objects should we describe in beans.xml ? All objects or only a few ?

The simplest answers are welcome

+5  A: 

Reconfiguration is overrated. The most important thing you get from using DI is testability. Since your classes don't depend on implementations but on abstractions you can replace them with mocks / stubs in your unit tests.

Example

Without DI:

class SaleAction{

 private BillingService billingService;

 public SaleAction(){
   billingService = new CreditCardService(); //dependency is hardcoded
 }

 public void pay(long amount){
   //pre payment logic
   billingService.pay(amount);
   //post payment logic
 }

}

In that example suppose you want to unit test the pre-payment logic and post-payment logic of SaleAction... you can't because SaleAction is coupled to CreditCardService and probably running your tests will generate fake payments.

Now the same example with DI:

 class SaleAction{

     private BillingService billingService;

     public SaleAction(BillingService service){
       billingService = service; //DI
     }

     public void pay(long amount){
       //pre payment logic
       billingService.pay(amount);
       //post payment logic
     }

    }

Now SaleAction is decoupled from any implementation, which means that in your test you can do SaleAction action = new SaleAction(new DummyBillingService());.

Hope that helps, there's also the article about DI, written by Martin Fowler that you can find here

Pablo Fernandez
effectively you are saying that DI frameworks, e.g. Spring, are overrated since it's trivial to replace dependencies with mocks in code without a framework. the creation of those mocks can be rather involved but I don't see any advantage in being able to swap them in and out for alternative mocks.
AdamRalph
not relying on concrete implementations is at the core of OOP, not only of DI.
Bozho
I don't say that frameworks are overrated. DI is mandatory for unit testing, and unit testing is mandatory for software development.
Pablo Fernandez
@Adam - I think you misunderstood the answer. For a simple problem Spring can be overly complex. A hand coded DI/configuration can be simpler in this situation. But at some point it's worth to use a DI framework as the wiring gets to complicated and other features supported by Spring are needed.
Thomas Jung
DI is not mandatory for unit testing.
Bozho
@Pablo - "unit testing is mandatory for software development" - Well, I could not work without unit testing, but I don't think that even the majority of software has unit test coverage.
Thomas Jung
@Thomas and @Bozho, that phrase was overemphasized just to get to the point quickly.
Pablo Fernandez
DI is **not** primarily about testing. It's a nice side-effect, though. See http://ayende.com/Blog/archive/2007/08/18/Dependency-Injection-More-than-a-testing-seam.aspx http://ayende.com/Blog/archive/2007/08/21/Dependency-Injection-Applicability-Benefits-and-Mocking.aspx
Mauricio Scheffer
@Mauricio, if you are not doing unit testing, there's no real need for DI.
Pablo Fernandez
@Pablo: take a look at Mark Seeman's answer and Ayende's articles I linked above. That's what DI is about.
Mauricio Scheffer
@Mauricio: personal experience and 'crazy' Bob Lee (Guice creator) says otherwise.
Pablo Fernandez
+2  A: 

Here's a good article explaining the ideas of spring. (By Rod Johnson, the founder of the Spring framework)

Bozho
+1  A: 

Opinion: Figure out what problem you try to solve with DI and take a framework that fits best. Spring could add to much complexity for your problem.

(One of the first articles about DI by Martin Fowler. I think the term DI was coined in this article.)

Thomas Jung
+7  A: 

We use Dependency Injection (DI) to implement loose coupling. The choice of any particulary DI Container is not that important.

Every time you create an instance of a class by using the new keyword, you tightly couple your code to that class, and you will not be able to substitute that particularl implementation with a different one (at least not without recompiling the code).

This would look something like this in C# (but would be equivalent in Java):

public class MyClass
{
    public string GetMessage(int key)
    {
        return new MessageService().GetMessage(key)
    }
}

This means that if you would later like to use a different MessageService, you can't.

On the other hand, if you inject an interface into the class and adhere to the Liskov Substition Principle, you will be able to vary the consumer and the service independently.

public class MyClass
{
    private readonly IMessageService messageService;

    public MyClass(IMessageService messageService)
    {
        if(messageService == null)
        {
            throw new ArgumentNullException("messageService");
        }

        this.messageService = messageService;
    }

    public string GetMessage(int key)
    {
        return this.messageService.GetMessage(key)
    }
}

Although this looks more complicated, we have now managed to follow the Single Responsibility Principle by ensuring that each collaborator does only one thing, and that we can vary both independently of each other.

Furthermore, we can now change MyClass' behavior without changing the class itself, thus adhering to the Open/Closed Principle.

Mark Seemann
+2  A: 

Spring has turned into a huge framework, which may be confusing you if you are only trying to wrap your head around dependency injection. The Google Guice project is tiny and only does DI with pure Java--no XML and no extras. There's a nice introductory video explaining DI too. http://code.google.com/p/google-guice/

Ken Fox
@Ken Fox. No, no. I will use Spring. DI was mentioned because it forms the basis of the Spring Framework. I'm not interested in DI, I am interested mainly in Spring functionality. but I need to know what lays in the base.
EugeneP
Spring has always been a huge framework, much more than DI. AOP has had equal billing since day one, as have the libraries. To say that Spring and Guice map one-to-one is as incorrect as saying the same for Spring MVC and Struts. Spring includes functionality equivalent to both and more.
duffymo
@Ken Fox. All right, I don't really understand yet AOP, I've read that it deals with "crosscutting concerns", things like logging that occur in virtually every method of the class. But tell me, all right, there's AOP. But it does not substitute DI, does it?
EugeneP
@duffymo: Who said Spring and Guice map one-to-one?! I suggested Guice because it only does DI and may be easier to understand if someone is only interested in DI.
Ken Fox
No, it's complementary. Did you learn anything from all those books you claim to have read?
duffymo
@Ken - I didn't suggest that you did, it's a response to the "huge framework" statement. I thought it implied that Spring had started life as a simple DI framework and ballooned in an uncontrolled way to something unwieldy. In my experience, there's a lot to Spring, but it's not necessary to understand or use all of it to get benefit from it. A la carte choices from Spring work well and play nicely with other technologies.
duffymo
@EugeneP: Don't pick a framework and then see what it does. There's an XP principle called YAGNI (You Ain't Gonna Need It) that has always been good to me. If you have a problem, find a solution, and if that brings you to a framework like Spring, at least you know where to start eating the elephant.
Ken Fox
@duffymo To answer your question, one should answer the question "What is learning and what 'to learn' means". I learned something from philosophy, so try to get me right ;)
EugeneP
I agree with Ken. It doesn't seem to me that Eugene is up to it yet.
duffymo
@Eugene - I think the bigger question here is "what reading is." I find it hard to believe that anyone could claim to have read the best books on any subject and come here to ask such an elementary question. What books did you read? Titles, please.
duffymo
Well Reinventing the wheel ?
EugeneP
@duffymo. Yes the question is simple but have you answered it? Many things in life seem simple when you do not need to explain [and CANNOT EXPLAIN] how it works and why. :)
EugeneP
@EugeneP - see how you like the modified answer. "cannot explain"? You be the judge.
duffymo
+2  A: 

I think I can take a crack at the question, although I'm not sure that any answer will be satisfactory.

The easy answer is that Spring is combination of technologies:

  1. dependency injection, which uses the Hollywood principle to help you keep interface and implementation separate;
  2. aspect oriented programming, which isolates cross cutting concerns into modules that you can apply declaratively. The "hello world" of AOP is logging, but it's all over Spring (e.g. transactions, dynamic proxies for remoting, security, etc.) Think servlet filters and you'll have the idea;
  3. libraries to help with common tasks like persistence (JDBC, Hibernate, iBatis, JDO, JPA, etc.), remoting (RMI, HTTP, web services), asynch messaging (message driven POJOs), validating and binding, web MVC (Spring or Struts), utilities like e-mail, scheduling, security, etc.

But the deeper answer is that you're getting the benefit of Rod Johnson's experience as a consultant on Java EE projects. He distilled what worked for him on his gigs into Interface 21/Spring, and now you can have the benefit of all that for free.

The Spring team writes code that is designed, tested, and follows standards more rigorously than anything I'll ever write. (Imagine Juergen Hoeller browbeating Rod Johnson because his code didn't meet the standard prior to check-in.) I can count on their framework code when I use it and concentrate on my business problem. I'm not writing boiler plate code again and again.

For me, Spring is more about an architectural template that acts as a guide for creating web apps. Some people might say that it's over-engineered, and for certain problems they're correct, but for the kind of problems that I'm faced with on a regular basis Spring is just the ticket.

As for the subquestions:

What advantages do we have when using dependency injection frameworks?

Objects don't have to be responsible for managing their dependencies. Spring's application context is really just a big Factory Pattern from the GoF. It encourages you to design to an interface so you can change the implementation as needed. Your persistence interface might use a JDBC implementation today, Hibernate tomorrow; you might decide to auto generate a proxy to manage its transactional behavior. None of the client code has to change if you code to an interface.

The idea of describing classes with setter values and/or constructor parameters seems strange to me. Why do that? Because we can change the properties without recompiling the project? Is that all what we gain?

Strange? You don't use properties or constructors in your code? You do it because that's the way most Java classes are written. Spring merely uses those mechanisms as a way to provide dependencies to the class.

Then, what objects should we describe in beans.xml ? All objects or only a few ?

Only the beans that have dependencies. I still call "new" for objects that are local to a particular method. They are created, used, and garbage collected in method scope. Those need not be under Spring's control.

duffymo
I cannot tell your answer covers all my sub-questions, but still it was interesting to read it. +1
EugeneP
See if the additions are better.
duffymo
+1  A: 

Here's a good video given by Bob Lee and two of his under studies about Guice (Guice is a dependency injection framework like Spring). The first 10 or so minutes are about why Guice (or dependency injection) would be better than the alternative (Factories) so it's not all just about Guice.

Droo
+2  A: 

You already have some good answers here, I want to address a couple specific questions you have:

The idea of describing classes with setter values and/or constructor parameters seems strange to me. Why do that? Because we can change the properties without recompiling the project? Is that all what we gain?

It does seem weird at first but the point is that the container is in charge of plugging in dependencies for the objects, the objects themselves are not in charge of that. The scope of the objects configured in beans.xml is managed by Spring, so we don't have to worry so much about things being instantiated without the right dependencies (as long as the configuration is correct, I have been known to write unit tests to check that the spring configuration is doing what I want it to.)

Then, what objects should we describe in beans.xml ? All objects or only a few ?

The kinds of objects described in beans.xml are mostly components--controllers, services, data access objects, and things that they need like transaction managers, hibernate session factories, data sources, stuff like that. Domain objects are typically retrieved from data access objects or instantiated directly, because they don't have dependencies on anything but other domain objects (or on utility classes that are even more independent than domain classes).

Nathan Hughes
+1  A: 

Maybe you should not attempt to undertake 'Java enterprise development' without some idea about the basic architectural and design concerns? I suggest you either find an experienced co-worker who is willing to help you, or invest some more effort in reading those books, or otherwise follow a course.

In any case, there is no 'simple answer' to your question.

Adriaan Koster
A: 

Dependency injection is a workaround for missing virtual classes!

 

NB: if you don't know what virtual classes are, please refer to "Virtual classes, anyone?".

Adrian
The horror of C++ multiple virtual inheritance will be with me forever. I like that article, but you need a new name. DI frameworks now use annotations so they are almost indistinguishable from a language feature--until two different frameworks collide and the illusion is shattered.
Ken Fox