Java IoC containers and classpath scanning (or what I’ve been looking for from .NET for months)
Not content with their answers I burrowed into Spring, Guice and PicoContainer docs and found “classpath scanning” which is roughly
equivalent to “autowire” in .NET. Below is an example of this in Spring 3:
MyStuff.java (my main class note his has 2 dependencies which you can view on my github repo)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service //one way of marking this as a component to register
public class MyStuff {
private final DependencyWithNoInterface first;
private final DependencyInterface second;
@Autowired //tells spring which constructor to use for it’s dependencies
public MyStuff(DependencyWithNoInterface first, DependencyInterface second) {
this.first = first;
this.second = second;
}
public void run(){
System.out.println(“foo me”);
first.foo();
second.superFoo();
}
}
appContext.xml (seems you still need some XML)
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xmlns:context=“http://www.springframework.org/schema/context”
xsi:schemaLocation=“http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd”>
Application.java (the initialization)
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Application {
public static void main(String args[]){
ApplicationContext ctx = new ClassPathXmlApplicationContext(“appContext.xml”); //the IoC container
MyStuff stff = ctx.getBean(MyStuff.class); //my fully injected class
stff.run();
}
}
Now I’m sure for the .NET developers familiar with StructureMap, Windsor, Autofac, etc this is completely unimpressive. I’m also sure there are Java developers that are somewhat unimpressed with this but for reasons that involve holding onto giant configuration artifacts. Manual IoC component registration falls where hand writing SQL for trivial data access does for me, extra repetitive work that has been solved years ago.
Edit:
It appears you can forgo XML as well in your main class use a different Application context and add the refresh and scan lines
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Application {
public static void main(String args[]){
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("org.foo"); //scans the org.foo package
ctx.refresh(); //needed to load them for some reason
MyStuff stff = ctx.getBean(MyStuff.class);
stff.run();
}
}