views:

106

answers:

3

When using spring and spring's MVC, where should the DI take place?

example, if you have a controller, and many actions in the controller.

Would you be doing:

@RequestMapping("/blah")
public String SomeAction()
{
    ApplicationContext ctx = new AnnotationConfigApplicationContext();
    MyService myService = ctx.getBean("myService");

    // do something here

    return "someView";
}

Would this be the best practice approach? Or is their a better way?

+2  A: 

dont use getbean, that lose the purpose of doing DI. use @Autowired . DI is mean to use on layer system like view, service, dao.. so that each layer not depending on each other

cometta
No cometta, one can still clutter things, i.e. make inappropriate dependencies, using DI. Your suggestion is correct, though.
Adeel Ansari
+7  A: 

The whole idea of Dependency Injection is to not have your classes know or care of how they get the objects they depend on. With injection, these dependencies should just "appear" without any request (hence the Inversion of Control). When using ApplicationContext#getBean(String), you're still asking for the dependency (a la Service Locator) and this is not Inversion of Control (even if this allows you to change the implementation easily).

So, instead, you should make your MyController a Spring managed bean and inject MyService using either setter or constructor based injection.

public class MyController {

    private MyService myService;

    public MyController(MyService aService) { // constructor based injection
        this.myService = aService;
    }

    public void setMyService(MySerice aService) { // setter based injection
        this.myService = aService;
    }

    @Autowired
    public void setMyService(MyService aService) { // autowired by Spring
        this.myService = aService;
    }

    @RequestMapping("/blah")
    public String someAction()
    {
        // do something here
        myService.foo();

        return "someView";
    }
}

And configure Spring to wire things together.

Pascal Thivent
I think it's important for newcomers to Spring MVC to understand that your controller is already being loaded and wired up by an ApplicationContext. Therefore, all you need to do is specify which other beans the controller should be wired up with.
matt b
You could add @Controller to the front of the class above to help Spring load it, especially if you use <context:annotation-config />
John
So any wired bean will be instatiated like: AnyBlah blah = new AnyBlah() ?
mrblah
@mrblah: Try that out, give it a go. And meanwhile we prepare an answer for your next question. Cheers.
Adeel Ansari
+1  A: 

As a compliment to Pascal's post, Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern is a must read.

And as cometta stated, that you should use @Autowire annotation to achieve that. In addition to that, Spring supports name based and type based convention injections. I suggest you to read on that.

Adeel Ansari