I am learning Spring and I have a question regarding how you use it in standalone applications (and also when using it for making web applications). The examples I have been coded so far has used a simple main method where I retrieve beans by calling getBean on the. Context object. However, you probably want to do this in multiple classes so do you first get a context and then call getBean or are there other cleaner alternatives? Or is this the way you do it in standalone and web apps?
4 Answers
If you're calling context.getBean()
everywhere, you're probably missing the whole point of Spring, which is a dependency injection framework.
In a standalone app, you typically call context.getBean()
only once (or at least, very rarely), in order to get a "root" bean. This bean is injected by Spring with other beans, and so on.
In a web app, it all depends on which framework you use. But typically, you register a listener in the web.xml which loads the context for you, and controllers are created and/or injected by Spring.

- 678,734
- 91
- 1,224
- 1,255
-
Oh, so you only use it for boot strapping the application. – LuckyLuke Mar 12 '12 at 21:56
-
Ok, thank you. Could you explain what you mean by that I miss the point of DI framework? So that I can read up. Also why are you supposedto only invoke it once? – LuckyLuke Mar 12 '12 at 22:03
-
DI implements the Hollywood principle: "don't call me, I'll call you". The goal is to avoid looking up your dependencies, and have them injected by Spring instead. This is what makes unit testing so easier. If you're looking up all the denendencies in the context, you're not doing DI anymore. You invoke it once in main because it's the absolute minimum. Everywhere else, you use DI. – JB Nizet Mar 12 '12 at 22:09
You're on the right lines. Your main method will initialise your application context as you've discovered. The trick then is to use that app context to create the entry point to your application. That bean, having been created with spring will have been wired for you..
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ApplicationMain {
public static void main(String[] args) {
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/META-INF/spring/applicationContext.xml");
MyApplication app = BeanFactoryUtils.beanOfType(ctx, MyApplication.class);
app.init();
}
}

- 7,278
- 1
- 26
- 36
-
i would just configure app.init as the init-method off app. this way the lookup and the explicit call are not needed. everything is handled by spring. – Laures Mar 12 '12 at 22:42
-
@Laures - Agree, this *can* be made more implicit, but sometimes an explicit call makes things clearer. Note that Spring has the `org.springframework.context.Lifecycle` interface which could be applicable here. When `start()`, `stop()` or `isRunning()` is called on an application context all beans implementing the Lifecycle interface have the equivalent method called. In simple examples like this I think it's overkill. – sw1nn Mar 14 '12 at 17:05
One class (your main class, probably) has to be Spring-aware to create the context. All other classes can continue to be wired together via Spring and do not need to be Context-aware.

- 85,615
- 20
- 155
- 190
It kind of depends on the application you are writing, but you should limit getBean()
invocations to minimum, preferably one. You are fetching the first bean directly from the context and put the rest of the logic in the beans themselves. Something along the lines:
Bootstrap boot = context.getBean(Bootstrap.class);
boot.start();
And all the rest of your application logic is taking place within start()
. It can create threads, listen for events, etc.

- 334,321
- 69
- 703
- 674