使用Spring和Spring的MVC时,dependency injection(DI)应该在哪里发生?
示例,如果您有控制器,并且控制器中有许多操作。
你会这样做:
@RequestMapping("/blah")
public String SomeAction()
{
ApplicationContext ctx = new AnnotationConfigApplicationContext();
MyService myService = ctx.getBean("myService");
// do something here
return "someView";
}
这是最佳做法吗?或者他们是更好的方式?
答案 0 :(得分:10)
依赖注入的整个想法是不让您的类知道或关心他们如何获得他们所依赖的对象。通过注入,这些依赖关系应该“出现”而没有任何请求(因此控制反转)。使用ApplicationContext#getBean(String)
时,您仍然要求依赖(服务定位器),这是不控制反转(即使这允许您轻松更改实现)。< / p>
因此,您应该使用基于setter或构造函数的注入使MyController
成为Spring托管bean并注入MyService
。
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";
}
}
并将Spring配置为连接在一起。
答案 1 :(得分:2)
不要使用getbean,这会失去做DI的目的。请改用@Autowired。 DI旨在用于分层系统,如视图,服务DAO,以便每个层不相互依赖。
答案 2 :(得分:1)
作为Pascal帖子的恭维, Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern是必读的。
正如彗星所说,你应该使用@Autowire
注释来实现这一点。除此之外,Spring还支持基于名称和基于类型的常规注入。我建议你继续阅读。