I like to refer to IoC as "good things come to those who wait",
Most of us are conditioned to "go out and
do things. But that's not how IoC works. IoC works with a framework and IoC objects simply tell the framework (
e. g., via an Annotation) that the framework should construct (vis the Spring
BeanFactory) and wire together sets of objects. This is very good, because it reduces chunks of the application to plug-in components which can be switch out for similar components. As, for example, if you have an app that blasts out emails, you chould create a standard emailer interface and implement 2 classes: a dummy emailer for
testing and a live emailer for production. Using Spring, you wire in the dummy one while you're debugging or maintaining and avoid spamming the world with a lot of test emails. Then have Spring wire in the production module when you're ready to go live.
In Spring, the
BeanFactory is where you start, since hopefully you're not using static variables. You can ask for a bean by name and Spring will locate it in its inventory (or construct it if it doesn't exist) and automatically create and connect any auto-wired beans that that bean has referenced, so you get a whole lot of functionality with relatively little effort.
Spring is not the only IoC service out there. In fact, there are a number of extinct IoC services I used to work with (Apache Avalon for instance). Another one is the
JEE standard JavaServer Faces framwork, whose own IoC services can be integrated with Spring via a simple configuration option to make the two factories work seamlessly in concert. The relatively recent
Java standard injection facility also supports IoC, although I find Spring to be more civilized.