@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?
换句话说,如果我有一个Service类,并且我将注释从@Service更改为@Component,它的行为是否仍然相同?
或者注释是否也会影响类的行为和功能?
@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?
换句话说,如果我有一个Service类,并且我将注释从@Service更改为@Component,它的行为是否仍然相同?
或者注释是否也会影响类的行为和功能?
当前回答
这里给出的答案在技术上是部分正确的,但即使答案列表很长,这将是底部,我认为在这里也应该给出一个真正正确的答案,以防有人偶然发现并从中学习到有价值的东西。这并不是说其余的答案完全错误,只是它们不正确。而且,为了阻止成群的巨魔,是的,我知道,从技术上讲,这些注释现在实际上是一样的,甚至到第5春,它们都可以互换。现在,对于正确的答案:
这三种注释是完全不同的,不可互换。你可以这么说,因为他们有三个而不是一个。它们并不是可互换的,它们只是出于优雅和方便而实现的。
现代编程是不同比例的发明、艺术、技术和通信。通信位通常非常重要,因为代码的读取频率通常比编写频率高得多。作为一名程序员,你不仅试图解决技术问题,还试图将你的意图传达给阅读你代码的未来程序员。这些程序员可能既不共享您的母语,也不共享您所处的社交环境,而且他们可能在未来50年内阅读您的代码(这并不像您想象的那样不可能)。在未来很难有效地沟通。因此,我们必须使用最清晰、最有效、最正确、最具交际能力的语言。我们谨慎地选择词汇,以产生最大的影响,并尽可能清楚地表达我们的意图。
例如,在编写存储库时使用@Repository而不是@Component是非常重要的。后者对于存储库来说是一个非常糟糕的注释选择,因为它并不表示我们正在查看存储库。我们可以假设存储库也是一个springbean,但不能假设组件是一个存储库。有了@Repository,我们的语言变得清晰而具体。我们明确表示,这是一个存储库。有了@Component,我们就让读者来决定他们阅读的是什么类型的组件,他们必须阅读整个类(以及可能的子类和接口树)来推断含义。在遥远的将来,该类可能会被读者误解为不是一个存储库,我们可能会对这个错误承担部分责任,因为我们深知这是一个存储,但未能在我们的语言中明确表达我们的意图。
我将不讨论其他示例,但将尽可能清楚地说明:这些注释是完全不同的东西,应根据其意图适当使用@存储库用于存储存储库,其他注释都不正确@服务用于服务,其他注释不正确@控制器适用于既不是存储库也不是服务的组件,在其位置使用其中任何一个都是不正确的。它可能会编译,甚至可能运行并通过您的测试,但这是错误的,如果您这样做的话,我会对您(专业)的评价降低。
整个春季都有这样的例子(以及一般的编程)。编写REST API时不能使用@Controller,因为@RestController可用。当@GetMapping是有效的替代方案时,不能使用@RequestMapping。你必须选择最具体、最准确、最正确的语言来向读者传达你的意图,否则,你会给你的系统带来风险,风险是有代价的。
最后,我想提出一个关于面向对象系统的问题。基本规则之一是,实现可以变化,但接口不应该变化。假设这些注释是相同的,这是一个非常棘手的问题,完全违背OO。尽管它们现在可能以可互换的方式实现,但不能保证将来会实现。此外,即使在同一个团队中,工程师也可能会决定使用方面暂停这些注释中的一个或多个,或者平台工程师可能会出于操作原因选择替换其中一个的实现。你只是不知道,也不应该知道——在OO中,你依赖的是接口,而不是实现。
其他回答
这里给出的答案在技术上是部分正确的,但即使答案列表很长,这将是底部,我认为在这里也应该给出一个真正正确的答案,以防有人偶然发现并从中学习到有价值的东西。这并不是说其余的答案完全错误,只是它们不正确。而且,为了阻止成群的巨魔,是的,我知道,从技术上讲,这些注释现在实际上是一样的,甚至到第5春,它们都可以互换。现在,对于正确的答案:
这三种注释是完全不同的,不可互换。你可以这么说,因为他们有三个而不是一个。它们并不是可互换的,它们只是出于优雅和方便而实现的。
现代编程是不同比例的发明、艺术、技术和通信。通信位通常非常重要,因为代码的读取频率通常比编写频率高得多。作为一名程序员,你不仅试图解决技术问题,还试图将你的意图传达给阅读你代码的未来程序员。这些程序员可能既不共享您的母语,也不共享您所处的社交环境,而且他们可能在未来50年内阅读您的代码(这并不像您想象的那样不可能)。在未来很难有效地沟通。因此,我们必须使用最清晰、最有效、最正确、最具交际能力的语言。我们谨慎地选择词汇,以产生最大的影响,并尽可能清楚地表达我们的意图。
例如,在编写存储库时使用@Repository而不是@Component是非常重要的。后者对于存储库来说是一个非常糟糕的注释选择,因为它并不表示我们正在查看存储库。我们可以假设存储库也是一个springbean,但不能假设组件是一个存储库。有了@Repository,我们的语言变得清晰而具体。我们明确表示,这是一个存储库。有了@Component,我们就让读者来决定他们阅读的是什么类型的组件,他们必须阅读整个类(以及可能的子类和接口树)来推断含义。在遥远的将来,该类可能会被读者误解为不是一个存储库,我们可能会对这个错误承担部分责任,因为我们深知这是一个存储,但未能在我们的语言中明确表达我们的意图。
我将不讨论其他示例,但将尽可能清楚地说明:这些注释是完全不同的东西,应根据其意图适当使用@存储库用于存储存储库,其他注释都不正确@服务用于服务,其他注释不正确@控制器适用于既不是存储库也不是服务的组件,在其位置使用其中任何一个都是不正确的。它可能会编译,甚至可能运行并通过您的测试,但这是错误的,如果您这样做的话,我会对您(专业)的评价降低。
整个春季都有这样的例子(以及一般的编程)。编写REST API时不能使用@Controller,因为@RestController可用。当@GetMapping是有效的替代方案时,不能使用@RequestMapping。你必须选择最具体、最准确、最正确的语言来向读者传达你的意图,否则,你会给你的系统带来风险,风险是有代价的。
最后,我想提出一个关于面向对象系统的问题。基本规则之一是,实现可以变化,但接口不应该变化。假设这些注释是相同的,这是一个非常棘手的问题,完全违背OO。尽管它们现在可能以可互换的方式实现,但不能保证将来会实现。此外,即使在同一个团队中,工程师也可能会决定使用方面暂停这些注释中的一个或多个,或者平台工程师可能会出于操作原因选择替换其中一个的实现。你只是不知道,也不应该知道——在OO中,你依赖的是接口,而不是实现。
这些是Stereotype注释,可用于自动扫描
从技术上讲,@Controller、@Service、@Repository都是相同的。它们都扩展了@Component。
从Spring源代码:
指示带注释的类是“组件”。当使用基于注释的配置和类路径扫描时,此类类被视为自动检测的候选类。
我们可以对每个bean直接使用@Component,但为了更好地理解和维护大型应用程序,我们使用@Controller、@Service、@Repository。
每个注释的目的:
@带有此注释的Controller->类旨在接收来自客户端的请求。第一个请求来自DispatcherServlet,它使用@RequestMapping注释的值将请求传递给特定的控制器。@带有此注释的服务->类旨在处理我们从客户端接收或从数据库获取的数据。所有的数据操作都应该在这个层中完成。@存储库->带有此注释的类用于连接数据库。它也可以被认为是DAO(数据访问对象)层。该层应仅限于CRUD(创建、检索、更新、删除)操作。如果需要任何操作,数据应发送回@Service层。
如果我们交换它们的位置(使用@Repository代替@Controller),我们的应用程序将正常工作。
使用三种不同的@注释的主要目的是为Enterprise应用程序提供更好的模块性。
@存储库@Service和@Controller用作@Component的专用化,以便更具体地使用。在此基础上,您可以将@Service替换为@Component,但在这种情况下,您会失去专用化。
1. **@Repository** - Automatic exception translation in your persistence layer.
2. **@Service** - It indicates that the annotated class is providing a business service to other layers within the application.
在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@Component中,@Service、@Controller和@Repository是Stereotype注释,用于:
@Controller:在完成了来自演示页面的请求映射的地方,即演示层不会转到任何其他文件,它会直接转到@Controller类,并在@RequestMapping注释中检查请求的路径,如果需要,该注释在方法调用之前编写。
@服务:所有业务逻辑都在这里,即与数据相关的计算和所有。此业务层注释中,我们的用户不直接调用持久性方法,因此将使用此注释调用此方法。它将根据用户请求请求@Repository
@存储库:这是用于从数据库获取数据的应用程序的持久层(数据访问层)。即,所有与数据库相关的操作都由存储库完成。
@组件-使用组件原型注释其他组件(例如REST资源类)。
指示带注释的类是“组件”。此类类为使用时被视为自动检测的候选项基于注释的配置和类路径扫描。其他类级别注释可被视为标识组件,通常是一种特殊类型的组件:例如@Repository注解或AspectJ的@Aspect注解。