What is the point of dependency injection as used in Spring? - java

I have been reading the book Spring in Action for a few weeks now to learn about the spring framework. I have about 2 years of programming experience mostly in java with some distractions here and there in Ruby and Python.
After reading the first few chapters, I didn't quite get what the big deal is about dependency injection in spring. I was expecting a AHAAA moment but didn't quite experience that yet. I'm sure I'm missing something important.
Why would I want to wire my beans in xml rather than instantiating them the good old way with the = new myclass();
I understand I can wire beans in the xml via constructor args and properties as well as configure datasources in spring so that I can hide away connection details in an xml file. But why? There is more to this especially when it comes to good software design. Can some one explain the big deal?

Three Words: INVERSION OF CONTROL
In a nutshell:
As soon as you instantaniate "the good old way" you create tight coupling, e.g.: your controller depends on a specific template engine, your entities on a concrete database layer, etc. And that's something you want to prevent and where the dependency injection container (DIC) comes in very handy. It manages your services and you don't really have to care anymore about specific implementations as long as those implement the same interface.
Imagine a simple storage layer class called InMemoryLayer that gets instantiated by you when need it. Now you want to switch it for an awesome new open-source github solution called SuperSecretRemoteCloudLayer. Normally you would now hit "Search and Replace" in your IDE of choice and replace all occurrences of InMemoryLayer with the SuperSecretRemoteCloudLayer. But that's not really handy and quite errorprone, why would you want to do all that hard work by hand? The DIC can do that for you and all you need to take care of, is that both *Layer implement the same interface (so your application won't break).

Spring's big deal is more about dependency injection, not XML-based configuration. As others have noted, Spring has been moving away from XML-based configuration. But DI is core to Spring.
The a-ha is that DI offers a different model for linking components together. Instead of components creating each other directly (and thus being tightly coupled), the components stop doing that, and you inject the linkages from a central location. It turns out that this helps with testing and transaction management in particular.

You don't truly appreciate Spring until you've had to do things the hard way. The hard way being maintaining multiple large projects without a coherent framework. If you have 4 big enterprise wide applications that all have their own way of starting themselves, and managing resources, you're in for a headache. If you know that each application uses spring, then just look for the application context xml! This also makes it incredibly easy to setup a new context for different environments, and test cases, all without mucking up your code base.

Related

Adapt standalone application to use Spring

I've read about how to use Spring in standalone applications but I'm not sure what should be the approach for refactoring a large code base of 120,000 lines for making the change as gradual as possible.
As far as I understand Spring won't inject anything in an object unless that object is managed by the application context. If this is true, I think I have two choices:
1- Start refactoring from the main class down, but this means complicated scenarios will appear soon.
2- Share the application context statically so that I can start refactoring the simplest things, scalating in difficulty when I'm ready.
I'm not a fan of static access so I would try to avoid that choice, but I don't know if it's a good idea to start with the huge classes that are loaded at startup. Any ideas of the best approach?
By the way, is it OK to inject Swing components until I can fix the dependencies?
I think that before approaching such a big technology change, it may be a good idea to start asking yourself if you are following the architecture that Spring guides you to have when you start using it from the beginning.
Therefore, is your application based on the MVC pattern?
If not, maybe your product is not yet ready for being refactored to
use Spring. In this case, I would suggest refactoring the product
design first, so that it complies with the MVC architectural pattern.
If yes, then I would proceed with a use-case-based approach, starting
from the use cases that required a complicated design and
implementation.
E.g. I would look for very important entity classes or business classes containing a lot of logic. This way, you can reduce the risk of doing a lot of refactoring before realizing that, for example, Spring is not a good fit for the core of your product.
After identifying the most critical use case, you can start to experiment how refactoring works on your current product by introducing Spring from end to end on a single critical scenario (user input - business logic - entity manipulation - persistence). If you are successful, then you keep refactoring, otherwise you can go back and try to understand where you need to change your current product before introducing Spring.
Of course, this works when you have some experience with Spring and you do not have to cope with newcomer's issues. If you are new to Spring, then I would recommend getting some experience with Spring before starting the adventure of refactoring such a big project.
Start simply and wire new code/class with spring. You'll amend your existing main method to initialise the ApplicationContext and load your new feature. Over time then as change requests arrive you'll refactor and migrate the existing codebase to use spring dependency injection.

Why does dependency injection require another language?

I'm comfortable programming in Java, but am fairly new to Spring. I've been reading about dependency-injection/inversion of control (and using it with Spring for the past few months), but I can't figure out the need for a separate language (xml/spring) to accomplish it.
What is wrong with creating a singleton in Java called DependencyHandler, and keeping everything in the same language? What are the advantages I get by using xml/Spring?
Dependency Injection does not require a separate language.
Spring is a framework for Java that historically required configuration in xml. Now you can configure it using xml, or java annotations.
Google's Guice is a simple dependency injection framework that has all configuration in Java.
There can be legitimate reasons why a custom language (in xml) can be better than Java for a specific purpose. For DI though, the reasons are stretchy, and in fact, not the real reasons.
From countless testimonies from happy Spring users, the overwhelming reason is that they somehow think xml is not code. They are so tired of writing boilerplate Java code, they are happy to switch to boilerplate xml. And that makes them happy.
Human beings are not rational when it comes to economic matters. We have elaborate systems that transfer resources in circles, finding comfort and security in such pointless waste of efforts.
But I guess happiness is the most important thing, however retarded it could be.
You can make dependency injection frameworks that use Java syntax, too. Just look at Google Guice, for example.
I'll answer the "benefits" part for XML specifically, although there aren't many.
Having configuration completely separate from code removes all framework artifacts from the source, which can be beneficial.
It's easier (not ridiculously so, but enough to be noteworthy) to create toolchains that affect configuration files: property loading/replacement, config-aware GUI config editors, documentation generation, etc.
Centralized configuration; instead of config being strewn around the codebase, it's in a group of files (or single file). This isn't an XML-only vitrue, it depends on how things are configured.
I think some types of configuration lend themselves to external configuration more than others. I choose based on what seems appropriate given the reqs, what the framework allows, and how the framework handles config aspects.
Spring is just an easy way to manage dependency injection in large projects.
But you can inject dependencies by using a static factory method on your class:
public class Foo
{
public Foo static mkFoo(/* dependencies */)
{
// assign dependencies to members
}
// ordinary class stuff
}
Then you just do Foo.mkFoo(/*dependencies*/) whenever you want a Foo. No spring required.
What is wrong with creating a singleton in Java called DependencyHandler, and keeping everything in the same language?
Handling all your dependencies in a single class is going to get messy quickly, and will result in coupling with all of your other classes. But that isn't a reason to not handle DI in plain java.

How advisable is migrating to spring framework?

Currently we have a framework(a customized MVC pattern in flex and command pattern in java) which works well with our use case. we are thinking about migration of our server to spring framework. How advisable it is?. our java framework is also loosely coupled.But I see spring more loosely coupled with some concepts Dependency injection and inversion of control( which i still need to get some idea).Basically in what kind of use-case people use spring.How efficient it is?.if its advisable also please let me know where to start with.
Using a framework like Spring or Guice helps you keep your applications organized and loosely coupled over time. A dependency injection framework essentially extracts object construction away from an application, allowing the application to focus on what it needs to do instead of any architectural concerns.
Another upfront advantage of using dependency injection is that your application no longer worries about object construction, thus allowing you to build mock objects to test each portion of you application independently.
I highly suggest reading Dhanji Prasanna's book Dependency Injection.
One benefit of moving to spring is that new developers you bring on will be more likely to know that tool, and may come up to speed faster.
That being said, rewriting an app needs to require a lot of justification. Is your current architecture failing you for any reason?

Why is the Spring framework called "non-intrusive"?

Spring framework is NON - INTRUSIVE.
Can you please elaborate this?
Thank You :)
Here, "non-intrusive" means that your application code doesn't need to depend on the Spring framework directly. Anything that can inject the appropriate dependencies will (theoretically) work just as well.
The main appeal of a nonintrusive framework is that it stays out of the way of your design and modelling activities. It stays completely out of the way until you need it.
It is perfectly possible to use Spring without any direct dependencies on the spring framework in your application code. That doesn't mean the code will continue to function without spring, since the functionality provided by spring will need to be replaced by another IoC container or code which directly instantiates all objects in a dependency chain, but it does mean that you can choose to wire things up with spring, or via some other mechanism.
However, to be really unintrusive with spring, you need to keep all of your configuration outside of your code, which means using XML for everything. This works beautifully in spring, but its a pain in the neck for developers and, since the advent of the widespread use of annotations in Java 5, isn't really the java way. So spring provides lots of annotations for wiring things together directly in your code. This can obviously create dependencies on Spring within the code, although all of the Spring tags are resolved at compile time, so you can still execute your classes outside of a spring context without any dependencies on spring jars and such. Also, wherever possible, custom spring annotations have been replaced with generic JEE annotations. With Spring 3, it is really pretty easy to use only JEE annotations plus a limited quantity of XML to initialize the application context.
The beauty of the spring way of doing things is that the underlying functionality which implements a feature can often be selected at runtime. If you are using an ORM system in a non-managed container for development, using a native session manager, you can easily switch to container managed sessions in production without changing any code whatsoever if you have configured the app to let spring handle transaction management. Methods that are marked as #Transactional will pick up a session and transaction automatically, regardless of the source, without any changes to the code. In fact, you can trivially switch to an entirely different ORM framework, if you are so inclined, though that's a pretty rare use case, in truth, so most applications will tend to have ORM framework specific code and/or queries in their data access code.
The difference between spring and an old-fashioned 'intrusive' framework is that intrusive frameworks often require you to implement particular interfaces or, even worse, force you to inherit from particular base classes, in order to access framework functionality. In the latter case, not only do you have a dependency on the framework you are using, but it severely limits your class hierarchy structure, too - in a language which only allows single inheritance. Recent versions of EJB learned from the elegance of Spring's (and others') less-intrusive model and EJB itself has since become much less intrusive (It's all about the POJOs).
I don't really see any support for irreputable's argument that spring is now a billion dollar beast that locks users in. Spring is, if anything, less intrusive than it has ever been while offering ever more functionality. It is certainly possible to lock yourself into spring, and a lot of devs are perfectly willing to do so precisely because the runtime overhead of using spring is so trivially small that most of us can't imagine a lot of scenarios in which we might remove spring from a project. If I want a fully managed JEE environment, I can configure for that (and run in the container of any available vendor). If I want to run in tomcat or jetty with 100% of configuration and runtime management coming from spring, I can do that, too. So I'm generally perfectly happy to use spring-specific functionality at the risk of lock-in unless the project requirements specifically forbid it. Spring adds very little overhead at runtime, so it is a low risk choice.
When push comes to shove, I find Spring to be far easier to learn than EJB. I can accomplish the same things with either methodology, but it is easier to bring in devs who are inexperienced if I'm using Spring compared to EJB, so hiring is easier, long term maintenance costs are lower, and release cycles are shorter.
No matter what the language direction, generally speaking, a framework is too intrusive, which is a voice of criticism, so I guess it is not because of this that non intrusiveness has become a "selling point" of publicity.
For example, spring and struts 2 use annotations, configuration files, conventions or reflection (other languages may be other ways) to achieve non-invasive, and the compilation and operation does not have formal dependence on the framework API.
But in essence, without this framework, our program simply cannot run correctly. These so-called annotations are customized. When and how they are processed are different. Think about the migration from gson to Jackson. The migration has costs and risks. Do you need users to write a new one?
In addition, how high is the probability of real migration? It feels very small.
years ago, there was this EJB beast, which was very "intrusive". Spring was touted to be a much simpler set of helper classes, and it was more like libraries than frameworks.
today, Spring becomes the new beast. As a billion dollar business, it is in their best interest to lock people in. Yeah, sure, you don't have a dependency problem, and you can quit Spring anytime.
With EJB, at least you have a few vendors to choose from.

Is there a simple framework allowing for Dependency Injection in a stand alone program?

We basically need to be able to adjust behaviour at start-up time, by providing desired classes to be produced by various factories inside our application (to avoid the hard binding of the "new" operator).
I am aware that this is provided by several large frameworks, but I was looking for something easily used by a stand-alone Java application without being gigantic.
Any suggestions?
Edit: It is my experience that frameworks tend to grow big as part of maturing (and complex too). I need this to be retrofittable to a legacy application as part of major refactoring (technical debt), so simplicity is essential of the used libraries. I do not mind having to do a bit of coding in our application, but it must be very visible what is going on. AOP has a tendency for moving stuff out of the way, and that may make the application harder to maintain.
Edit: We have now reached the point where we actually need to make a decision. The application will probably live for decades so we need to make a reversible decision with a framework that will be maintained for hopefully as long. I really like the static type check available with Guice, but not that the annotations bind explicitly to Guice instead of being external like in Spring. I also like that code appears to be more concise when using Guice as opposed to Spring. We need something that is robust and helpful. We do not need more than just DI at the moment. Is there a use case that definitive says go for one of these?
Edit 2011-07-27: The final decision was to use the JSR-330 API in code, and choose on a per-project basis if to use Spring, Guice or Weld. For stand-alone applications Guice has worked well so far as the JSR-330 implementation.
You can always use Spring Framework 2.5. It is a big one, but if you planning to use only DI you can use spring-core and spring-beans modules, which are pretty small (ca. 500KB and 300KB).
There is also Google Guice 2.0 which comes with a package with only basic stuff (no AOP) and it's 430KB.
Have you looked at the Google Guice framework? It's pretty lightweight and annotation-based, avoiding XML configuration files
There's also Pico- and Nano-container (from codehaus) which are quite lightweight although the last time I looked (admittedly a few years ago) the documentation was lacking.
I must say that I agree with others about what I assume is your presumption that Spring is massive and confusing. It's really a very simple IoC container and to be recommended.
There are a couple I know of you might find useful:
PicoContainer
Plexus (used in Maven)
I've found Plexus very useful in standalone apps as it has optional utility components for CLI interaction.
By "gigantic" I'm going to assume you're referring to Spring, but that's unfair, since you can cherry-pick the bits of Spring you want to use. If all you need is the IoC container, just use the appropriate JAR files and the appropriate bit of the API, and ignore the rest of it.
Most answers so far seem to be concerned with the size of the jar files to be added.
However I think the more important question is the impact on the project: How many lines of code must be added/changed in order to use the framework?
Even the "big" spring framework is actually very easy to use:
You basically need:
a xml file that describes your factories.
one line of code to initialize the container by loading the xml file
The nice thing is that spring is non-intrusive. So you do not have to implement specific interfaces or add any specific annotations or imports to your classes.
At best the single spot where you actually initialize the Spring container is the only
place in your application that has an actual dependency to spring classes.
I would strongly suggest to take a look at Spring ME. Although originally meant to be a way to use Spring on Java ME applications, it also works fine for standalone applications.
True, it doesn't give you all of the bells and whistles that Spring (Full) has to offer, but then again, Full Spring is much much more than a simple dependency injection framework.
On the plus side: it's based on a (compliant) subset of Spring's configuration files, and the footprint of the runtime is 0%. In fact, there isn't any. Spring ME will take your application context, and turn it into a class that has no dependencies on classes other than your own.
What's wrong with Spring?
These days it's packaged pretty well so you wouldn't need to take the whole kit and caboodle.
As an aside, I'm not a fan of the annotation based injection frameworks. This is because the annotations are bound to the class rather than the instance, the later being a pre-requisite, imho, for DI. This means every instance of a given class gets the same object(s) injected, which seems to defeat the point.
Also consider that DI doesn't even need a framework, what's wrong with your main method wiring together the application?
If you want something maximally simple and appropriate, then write some code that does what you want done. Presumably this involves wiring together factories based partly on fixed logic, and partly on run-time settings.
This has the advantage that the set of possible run-time configurations is known, and so documentable and testable.
It has the disadvantage that an deploying an unanticipated logic change inherently takes an extra second or so of compile time, and (more significantly) can't be sneaked into production without full testing by disguising it as 'just a configuration change'.
About a year ago I asked myself a question very like this. So I spend a few hours reading the Spring and Guice documentation. After about an hour with Spring I was left feeling that I could get a basic web app going, but had no idea how to use it in a stand alone application. After an hour with the Guice document everything had clicked and I could see just how I to do what I wanted to get done.
Now on to recommending Guice? Well no. What does your team already know? If someone already knows say Spring leaver that knowledge and have them spread it about. Like wise with Guice or Pico.
If you want something really light weight you might want to have a look at fuse it's fairly extendable so might be what you're looking for.
cheers
N

Categories