@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?
换句话说,如果我有一个Service类,并且我将注释从@Service更改为@Component,它的行为是否仍然相同?
或者注释是否也会影响类的行为和功能?
@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?
换句话说,如果我有一个Service类,并且我将注释从@Service更改为@Component,它的行为是否仍然相同?
或者注释是否也会影响类的行为和功能?
当前回答
在Spring 4中,最新版本:
@Repository注释是满足存储库的角色或原型(也称为数据访问对象或DAO)。该标记的用途之一是自动翻译第20.2.2节“例外翻译”中所述的例外。Spring提供了更多的原型注释:@Component、@Service、,和@Controller@组件是任何Spring管理的组件@Repository、@Service和@Controller是@Component的专门化,用于更具体的用例例如,在持久性、服务和表示层中,分别地因此,可以使用@组件,但使用@Repository、@Service或@相反,您的类更适合通过工具处理或与方面相关。例如,这些原型注释是切入点的理想目标。它也是@Repository、@Service和@Controller可能携带Spring框架未来版本中的附加语义。因此如果您选择使用@Component或@Service服务层,@service显然是更好的选择。同样,作为如上所述,@Repository已被支持作为持久化层中的自动异常转换。
其他回答
它们几乎相同——所有这些都意味着这个类是一个Spring bean@Service、@Repository和@Controller是专门的@Components。您可以选择与他们一起执行特定操作。例如:
@springmvc使用控制器bean@存储库bean有资格进行持久性异常转换
另一件事是将组件语义上指定给不同的层。
@Component提供的一点是,您可以用它注释其他注释,然后以与@Service相同的方式使用它们。
例如,最近我做了:
@Component
@Scope("prototype")
public @interface ScheduledJob {..}
因此,所有用@ScheduledJob注释的类都是springbean,除此之外,它们还注册为石英作业。您只需要提供处理特定注释的代码。
存储库和服务是组件注释的子级。所以,它们都是组件。存储库和服务只是扩展它。具体如何?服务只有意识形态上的区别:我们把它用于服务。存储库具有特定的异常处理程序。
In-spring框架提供了一些特殊类型的注释,称为原型注释。具体如下:-
@RestController- Declare at controller level.
@Controller – Declare at controller level.
@Component – Declare at Bean/entity level.
@Repository – Declare at DAO level.
@Service – Declare at BO level.
上面声明的注释是特殊的,因为当我们将<context:componentscan>添加到xxx-servlet.xml文件中时,spring将自动创建那些在上下文创建/加载阶段用上面的注释注释的类的对象。
这里给出的答案在技术上是部分正确的,但即使答案列表很长,这将是底部,我认为在这里也应该给出一个真正正确的答案,以防有人偶然发现并从中学习到有价值的东西。这并不是说其余的答案完全错误,只是它们不正确。而且,为了阻止成群的巨魔,是的,我知道,从技术上讲,这些注释现在实际上是一样的,甚至到第5春,它们都可以互换。现在,对于正确的答案:
这三种注释是完全不同的,不可互换。你可以这么说,因为他们有三个而不是一个。它们并不是可互换的,它们只是出于优雅和方便而实现的。
现代编程是不同比例的发明、艺术、技术和通信。通信位通常非常重要,因为代码的读取频率通常比编写频率高得多。作为一名程序员,你不仅试图解决技术问题,还试图将你的意图传达给阅读你代码的未来程序员。这些程序员可能既不共享您的母语,也不共享您所处的社交环境,而且他们可能在未来50年内阅读您的代码(这并不像您想象的那样不可能)。在未来很难有效地沟通。因此,我们必须使用最清晰、最有效、最正确、最具交际能力的语言。我们谨慎地选择词汇,以产生最大的影响,并尽可能清楚地表达我们的意图。
例如,在编写存储库时使用@Repository而不是@Component是非常重要的。后者对于存储库来说是一个非常糟糕的注释选择,因为它并不表示我们正在查看存储库。我们可以假设存储库也是一个springbean,但不能假设组件是一个存储库。有了@Repository,我们的语言变得清晰而具体。我们明确表示,这是一个存储库。有了@Component,我们就让读者来决定他们阅读的是什么类型的组件,他们必须阅读整个类(以及可能的子类和接口树)来推断含义。在遥远的将来,该类可能会被读者误解为不是一个存储库,我们可能会对这个错误承担部分责任,因为我们深知这是一个存储,但未能在我们的语言中明确表达我们的意图。
我将不讨论其他示例,但将尽可能清楚地说明:这些注释是完全不同的东西,应根据其意图适当使用@存储库用于存储存储库,其他注释都不正确@服务用于服务,其他注释不正确@控制器适用于既不是存储库也不是服务的组件,在其位置使用其中任何一个都是不正确的。它可能会编译,甚至可能运行并通过您的测试,但这是错误的,如果您这样做的话,我会对您(专业)的评价降低。
整个春季都有这样的例子(以及一般的编程)。编写REST API时不能使用@Controller,因为@RestController可用。当@GetMapping是有效的替代方案时,不能使用@RequestMapping。你必须选择最具体、最准确、最正确的语言来向读者传达你的意图,否则,你会给你的系统带来风险,风险是有代价的。
最后,我想提出一个关于面向对象系统的问题。基本规则之一是,实现可以变化,但接口不应该变化。假设这些注释是相同的,这是一个非常棘手的问题,完全违背OO。尽管它们现在可能以可互换的方式实现,但不能保证将来会实现。此外,即使在同一个团队中,工程师也可能会决定使用方面暂停这些注释中的一个或多个,或者平台工程师可能会出于操作原因选择替换其中一个的实现。你只是不知道,也不应该知道——在OO中,你依赖的是接口,而不是实现。
来自Spring文档:
@Repository注释是满足存储库的角色或原型(也称为数据访问对象或DAO)。该标记的用途之一是自动翻译异常,如异常转换中所述。Spring提供了更多的原型注释:@Component、@Service、,和@Controller@组件是任何Spring管理的组件@Repository、@Service和@Controller是@Component的专门化,用于更具体的用例(在持久性、服务和表示层)。因此,您可以使用@component注释组件类,但是,通过用@Repository、@Service或@Controller注释它们相反,您的类更适合由工具处理或与方面相关。例如,这些原型注释成为切入点的理想目标@存储库、@Service和@控制器还可以在未来版本的Spring框架。因此,如果您在使用@组件或服务层的@Service,@Service显然是更好的选择。同样,如前所述,@Repository已经支持作为自动异常转换的标记持久层。
Annotation | Meaning |
---|---|
@Component |
generic stereotype for any Spring-managed component |
@Repository |
stereotype for persistence layer |
@Service |
stereotype for service layer |
@Controller |
stereotype for presentation layer (spring-mvc) |