Note that the container determines that the Juicer requires a Peelable and a Peeler as constructor arguments and the container satisfies that requirement without ant code or XML directing it to do so. Neat.
Dependency Injection was popularized mainly by the SpringFramework Inversion of Control container but first noted by Robert Martin in a 1996 article.
<project name="pico" default="run" basedir="."> <property name="src" location="src/main/java"/> <property name="test.src" location="src/test/java"/> <property name="build" location="build"/> <property name="build.classes" location="build/main/classes"/> <path id="classpath"> <pathelement location="${build.classes}"/> <pathelement location="/Users/greghelton/dev/bin/pico/picocontainer-2.9.jar"/> </path> <path id="test.classpath"> <pathelement path="${classpath}"/> <pathelement location="/users/greghelton/dev/lib/junit/junit-4.6.jar"/> <pathelement path="${build.classes}"/> <pathelement path="${test.classes}"/> </path> <target name="clean"> <delete dir="${build}"/> </target> <target name="init" depends="clean"> <mkdir dir="${build.classes}"/> <mkdir dir="${test.classes}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build.classes}" classpathref="classpath"/> <javac srcdir="${test.src}" destdir="${test.classes}"> <classpath><path refid="classpath.path"/></classpath> </javac> </target> <target name="run" depends="compile"> <java classname="App"> <classpath><path refid="classpath"/></classpath> </java> </target> </project>
import org.picocontainer.MutablePicoContainer; import org.picocontainer.DefaultPicoContainer; public class App { public static void main(String[] args) { MutablePicoContainer pico = new DefaultPicoContainer(); pico.addComponent(Apple.class); pico.addComponent(Juicer.class); pico.addComponent(Peeler.class); Juicer juicer = (Juicer) pico.getComponent(Juicer.class); juicer.juice(); } }
public class Apple implements Peelable { public void peel() { } }
public class Juicer { private final Peelable peelable; private final Peeler peeler; public Juicer(Peelable peelable, Peeler peeler) { this.peelable = peelable; this.peeler = peeler; } public void juice() { System.out.println("Juicing <" + peelable + "> <" + peeler + ">"); } }
public interface Peelable { void peel(); }
import org.picocontainer.Startable; public class Peeler implements Startable { private final Peelable peelable; public Peeler(Peelable peelable) { this.peelable = peelable; } public void start() { peelable.peel(); } public void stop() { } }