我正在读书Pro Spring 3。其中有一段确实让我很困惑。该段落是关于 Spring 中的自动装配。以下是摘录:
在大多数情况下,是否应该使用问题的答案 自动装配绝对是“不!”自动装配可以节省您的时间 应用程序,但在许多情况下,它会导致不良实践,并且 在大型应用中不灵活。 使用 byName 似乎是一个不错的选择 想法,但它可能会导致你给你的班级人造财产 名称,以便您可以利用自动装配功能。 Spring 背后的整个想法是你可以创建你的类 你喜欢 Spring 并让 Spring 为你工作,而不是相反......
...对于任何重要的应用程序,请完全避免自动装配 成本。
我一直在我创建的应用程序中使用@Autowired 标签。有人可以解释一下它有什么问题以及我应该用什么来代替吗?
我现在如何处理大多数事情的一个小例子是:
@Service("snippetService")
public class SnippetService {
@Autowired
private TestService testService;
public Snippet getSnippet() {
return testService.getSnippet();
}
}
像这样使用自动装配是“错误的”还是我错过了什么?
我相信这里有两件事令人困惑。本章中“自动装配”的意思是标记 bean 以自动检测和注入依赖项。这可以通过设置“autowire”bean 属性来实现。
这实际上与使用
@Autowired
相反,在其中明确指示用于依赖注入的字段或设置器。
为了解释它,假设你有
public class SnippetService {
private TestService testService;
public Snippet getSnippet() {
return testService.getSnippet();
}
public void setTestService(TestService testService) {
this.testService = testService;
}
}
如果你定义了一个bean:
<bean class="mypackage.SnippetService" autowire="byType"/>
spring 将尝试通过调用 setTestService setter 来注入匹配类型的 bean,在本例中为
TestService
。即使您没有使用@Autowired
。这确实很危险,因为有些 setter 可能不适合被 spring 调用。
如果设置 autowire="no",则不会注入任何内容,除非用
@Autowired
、@Resource
、@Inject
进行标记。
您所拥有的没有任何问题,特别是如果您无论如何都从
TestService
的一种实现开始。正如 Johan 提到的,最好使用 @javax.annotation.Resource
,如果需要,它还可以让您更加具体(例如使用 name
或 type
属性)。
我在这里看到的唯一问题是你有点失去控制。例如,假设您的应用程序配置中有两个或多个
TestService
实例,并且您想使用其中之一。使用 Autowire
比使用配置 XML 来注入更棘手。这就是您的书试图指出的,即在此类需求更频繁的大型应用程序中,它变得困难/棘手。
如果你没有这样的情况,我想也没关系。
如果您进行基于构造函数的自动装配,通过 XML 自动装配是完全安全且有用的,特别是如果您将协作者设置为私有最终版本。
几年前,当我在一个非常大的 spring 2.5 项目上执行上述操作时,作者这么说让我感到很震惊。 (当时注释支持在 JBoss 中不起作用)