This might be a naive question. I\'m currently learning the Spring framework and dependency injection. While the basic principle of DI is rather easy to grasp, it\'s
Granted, this is a contrieved example, and with more complex object relationships it might be more efficient to stash up an XML file than writing it programmatically, but surely there must be more to it than that?
I think it makes more sense to put the "wiring up" in a configuration file rather than doing it manually in code for several reasons:
sawmill
to use a different instance of Saw
) can simply be made to the external (XML) file and do not require changing code, re-compiling, re-deploying, etc.Controller
class which gets a Service
class which contains your business logic, which uses a DAO
to obtain Saw
s from the database, which gets a DataSource
injected into it, etc.), manually wiring up the collaborators is tedious and requires a few dozen lines of code that do nothing but wiring up. If you hard-code the inserted class, you need that class be available at compile-time. With a configuration-file you could change the used saw (in your case) at runtime without recompiling and even use a saw taken from a new jar you just placed in the classpath. If it is worth the extra complexity is dependent on the task you have to solve.
Spring has three features that are equally important:
I'll agree that it's hard to see an advantage to dependency injection when you compare that to a single call to new. In that case, the latter will certainly look simpler, because it's a single line of code. Spring's configuration will always increase the lines of code, so it's not a winning argument.
It starts looking a lot better when you can take a cross-cutting concern like transactions out of your classes and use aspects to set them up in a declarative way. The comparison to a single "new" call isn't what Spring was created for.
Perhaps the best outcome from using Spring is the way its recommended idiom uses interfaces, layering, and good principles like DRY. It's really just the distillation of object-oriented best practices that Rod Johnson used in his consulting gigs. He found that the code he built up over time helped him make a buck delivering better software for his clients. He summarized his experience in "Expert 1:1 J2EE" and ended up open sourcing the code as Spring.
I'd say buy into the framework to the degree that you think his experience can help you write better code, too.
I don't think you can get the full value of Spring until you combine all three of those features.
I generally don't care about XML or Reflection based DI because, in my use cases, it adds unnecessary complexity. Instead, I usually go for some form of manual DI that, to me, seems more natural and has most of the benefits.
public class SawDI{
public Saw CreateSaw(){
return new HandSaw();
}
public SawMill CreateSawMill(){
SawMill mill = new SawMill();
mill.SetSaw(CreateSaw());
return mill;
}
}
// later on
SawDI di = new SawDI();
SawMill mill = di.CreateSawMill();
This means I still centralize the coupling and have all the advantages of that, without the dependency on more complex DI framework or the XML configuration files.
Don't forget one major disadvantage of dependency injection: you loose the ability to easily find out from where something is initialized using Find Usages of your powerful Java IDE. This might be a very serious point if you refactor a lot and want to avoid that the test code is 10 times bigger than the application code.
It's important to understand that Spring is fundamentally two things, one built on top of the other:
(2) is the bulk of the Spring code. Basically pick a Java technology and you'll probably find Spring has helper classes for it. This is so you can use ActiveMQ, Sun One MQ or whatever and abstract them being a Spring JmsTemplate and the same goes for data access technologies, Web services, etc.
All of these helpers use (1) to wire them together.