@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?

换句话说,如果我有一个Service类,并且我将注释从@Service更改为@Component,它的行为是否仍然相同?

或者注释是否也会影响类的行为和功能?


当前回答

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将自动创建那些在上下文创建/加载阶段用上面的注释注释的类的对象。

其他回答

@Component、@Repository、@Controller和@Service注释之间的差异

@组件–通用,可跨应用程序使用@服务–在服务层级别注释类@控制器–注释表示层级别的类,主要用于SpringMVC。@Repository–在持久层注释类,它将充当数据库存储库。

@控制器=@Component(内部注释)+表示层功能@服务=@Component(内部注释)+服务层功能@分量=实际分量(豆类)@Repository=@Component(内部注释)+数据层特性(用于处理域bean)

@组件在配置类中充当@Bean注释,在spring上下文中注册Bean。它也是@Service、@Repository和@Controller注释的父级。

@服务,扩展了@Component注释,只有命名差异。

@Repository-扩展@Component注释并将所有数据库异常转换为DataAccessException。

@控制器-在MVC模式中充当控制器。分派器将扫描这些带注释的类以查找映射方法,检测@RequestMapping注释。

在Spring@Component中,@Service、@Controller和@Repository是Stereotype注释,用于:

@Controller:在完成了来自演示页面的请求映射的地方,即演示层不会转到任何其他文件,它会直接转到@Controller类,并在@RequestMapping注释中检查请求的路径,如果需要,该注释在方法调用之前编写。

@服务:所有业务逻辑都在这里,即与数据相关的计算和所有。此业务层注释中,我们的用户不直接调用持久性方法,因此将使用此注释调用此方法。它将根据用户请求请求@Repository

@存储库:这是用于从数据库获取数据的应用程序的持久层(数据访问层)。即,所有与数据库相关的操作都由存储库完成。

@组件-使用组件原型注释其他组件(例如REST资源类)。

指示带注释的类是“组件”。此类类为使用时被视为自动检测的候选项基于注释的配置和类路径扫描。其他类级别注释可被视为标识组件,通常是一种特殊类型的组件:例如@Repository注解或AspectJ的@Aspect注解。

这里给出的答案在技术上是部分正确的,但即使答案列表很长,这将是底部,我认为在这里也应该给出一个真正正确的答案,以防有人偶然发现并从中学习到有价值的东西。这并不是说其余的答案完全错误,只是它们不正确。而且,为了阻止成群的巨魔,是的,我知道,从技术上讲,这些注释现在实际上是一样的,甚至到第5春,它们都可以互换。现在,对于正确的答案:

这三种注释是完全不同的,不可互换。你可以这么说,因为他们有三个而不是一个。它们并不是可互换的,它们只是出于优雅和方便而实现的。

现代编程是不同比例的发明、艺术、技术和通信。通信位通常非常重要,因为代码的读取频率通常比编写频率高得多。作为一名程序员,你不仅试图解决技术问题,还试图将你的意图传达给阅读你代码的未来程序员。这些程序员可能既不共享您的母语,也不共享您所处的社交环境,而且他们可能在未来50年内阅读您的代码(这并不像您想象的那样不可能)。在未来很难有效地沟通。因此,我们必须使用最清晰、最有效、最正确、最具交际能力的语言。我们谨慎地选择词汇,以产生最大的影响,并尽可能清楚地表达我们的意图。

例如,在编写存储库时使用@Repository而不是@Component是非常重要的。后者对于存储库来说是一个非常糟糕的注释选择,因为它并不表示我们正在查看存储库。我们可以假设存储库也是一个springbean,但不能假设组件是一个存储库。有了@Repository,我们的语言变得清晰而具体。我们明确表示,这是一个存储库。有了@Component,我们就让读者来决定他们阅读的是什么类型的组件,他们必须阅读整个类(以及可能的子类和接口树)来推断含义。在遥远的将来,该类可能会被读者误解为不是一个存储库,我们可能会对这个错误承担部分责任,因为我们深知这是一个存储,但未能在我们的语言中明确表达我们的意图。

我将不讨论其他示例,但将尽可能清楚地说明:这些注释是完全不同的东西,应根据其意图适当使用@存储库用于存储存储库,其他注释都不正确@服务用于服务,其他注释不正确@控制器适用于既不是存储库也不是服务的组件,在其位置使用其中任何一个都是不正确的。它可能会编译,甚至可能运行并通过您的测试,但这是错误的,如果您这样做的话,我会对您(专业)的评价降低。

整个春季都有这样的例子(以及一般的编程)。编写REST API时不能使用@Controller,因为@RestController可用。当@GetMapping是有效的替代方案时,不能使用@RequestMapping。你必须选择最具体、最准确、最正确的语言来向读者传达你的意图,否则,你会给你的系统带来风险,风险是有代价的。

最后,我想提出一个关于面向对象系统的问题。基本规则之一是,实现可以变化,但接口不应该变化。假设这些注释是相同的,这是一个非常棘手的问题,完全违背OO。尽管它们现在可能以可互换的方式实现,但不能保证将来会实现。此外,即使在同一个团队中,工程师也可能会决定使用方面暂停这些注释中的一个或多个,或者平台工程师可能会出于操作原因选择替换其中一个的实现。你只是不知道,也不应该知道——在OO中,你依赖的是接口,而不是实现。

@组件、@Repository、@Service、@Controller:

@Component是由Spring@Repository、@Service和@Controller管理的组件的通用原型,是用于更具体用途的@Component专用化:

@持久性存储库@服务和交易服务@MVC控制器的控制器

为什么在@Component上使用@Repository、@Service、@Controller?我们可以用@component标记我们的组件类,但如果相反,我们使用适应预期功能的替代方法。我们的类更适合每种特定情况下的预期功能。

用@Repository注释的类使用org.springframework.dao.DataAccessException具有更好的翻译和可读错误处理。非常适合实现访问数据的组件(DataAccessObject或dao)。

带有@Controller的注释类在SpringWebMVC应用程序中扮演控制器角色

带有@Service的注释类在业务逻辑服务中发挥作用,例如DAO Manager(Facade)的Facade模式和事务处理