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

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

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


当前回答

来自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)

其他回答

Spring2.5引入了更多的原型注释:@Component、@Service和@Controller@组件充当任何Spring管理组件的通用原型;而@Repository、@Service和@Controller作为@Component的特殊化,用于更具体的用例(例如,分别在持久性、服务和表示层)。这意味着你可以用@component来注释你的组件类,但是通过用@Repository、@Service或@Controller来注释它们,你的类更适合由工具处理或与方面关联。例如,这些原型注释是切入点的理想目标。当然,@Repository、@Service和@Controller也有可能在未来的Spring Framework版本中携带额外的语义。因此,如果您在服务层使用@Component或@Service之间做出决定,@Service显然是更好的选择。类似地,如上所述,@Repository已经被支持作为持久层中自动异常转换的标记。@组件–表示自动扫描组件。@Repository–表示持久层中的DAO组件。@服务–表示业务层中的服务组件。@控制器–表示表示层中的控制器组件。

参考:-Spring Documentation-Classpath扫描、托管组件和使用Java编写配置

它们几乎相同——所有这些都意味着这个类是一个Spring bean@Service、@Repository和@Controller是专门的@Components。您可以选择与他们一起执行特定操作。例如:

@springmvc使用控制器bean@存储库bean有资格进行持久性异常转换

另一件事是将组件语义上指定给不同的层。

@Component提供的一点是,您可以用它注释其他注释,然后以与@Service相同的方式使用它们。

例如,最近我做了:

@Component
@Scope("prototype")
public @interface ScheduledJob {..}

因此,所有用@ScheduledJob注释的类都是springbean,除此之外,它们还注册为石英作业。您只需要提供处理特定注释的代码。

这些是Stereotype注释,可用于自动扫描

从技术上讲,@Controller、@Service、@Repository都是相同的。它们都扩展了@Component。

从Spring源代码:

指示带注释的类是“组件”。当使用基于注释的配置和类路径扫描时,此类类被视为自动检测的候选类。

我们可以对每个bean直接使用@Component,但为了更好地理解和维护大型应用程序,我们使用@Controller、@Service、@Repository。

每个注释的目的:

@带有此注释的Controller->类旨在接收来自客户端的请求。第一个请求来自DispatcherServlet,它使用@RequestMapping注释的值将请求传递给特定的控制器。@带有此注释的服务->类旨在处理我们从客户端接收或从数据库获取的数据。所有的数据操作都应该在这个层中完成。@存储库->带有此注释的类用于连接数据库。它也可以被认为是DAO(数据访问对象)层。该层应仅限于CRUD(创建、检索、更新、删除)操作。如果需要任何操作,数据应发送回@Service层。

如果我们交换它们的位置(使用@Repository代替@Controller),我们的应用程序将正常工作。

使用三种不同的@注释的主要目的是为Enterprise应用程序提供更好的模块性。

A@Service引用spring文档,

指示带注释的类是最初定义的“服务”被领域驱动设计(Evans,2003)称为“接口在模型中独立,没有封装状态。"也可以表示类是“业务服务外观”(在核心J2EE模式感觉)或类似的东西。此注释是通用刻板印象和单个团队可能会缩小语义并酌情使用。

如果你看看eric evans的领域驱动设计,

SERVICE是作为独立于模型,没有封装状态,作为ENTITIES和VALUE OBJECTS服务是技术框架中的一种常见模式,但它们也可以应用于域层。名称服务强调与其他对象的关系。与实体和价值对象不同纯粹是根据它可以为客户做什么来定义的。服务倾向于以活动而非实体命名,而不是动词而不是名词。SERVICE仍然可以具有抽象的、故意的释义它只是有一种不同于对象服务仍应具有明确的责任责任和履行责任的接口应定义为域模型的一部分。操作名称应来自通用语言或被引入其中。参数和结果应该是域对象。应明智地使用服务,而不是允许删除实体和值对象的所有行为。但当一个操作实际上是一个重要的领域概念时服务是模式驱动设计的自然组成部分。声明于将模型作为一种服务,而不是作为一个假的对象实际上,独立操作不会误导任何人任何人

以及根据Eric Evans,

REPOSTORY将特定类型的所有对象表示为概念对象设置(通常是模拟的)。它就像一个集合,除了有更多详细的查询功能。适当类型的对象包括添加和删除,以及REPOSTORY插件后面的机械或从数据库中删除它们。此定义收集了提供访问根从生命周期早期到生命周期结束的聚集。

Spring提供了四种不同类型的自动组件扫描注释,它们是@component、@Service、@Repository和@Controller。从技术上讲,它们之间没有区别,但每个自动组件扫描注释都应用于特定目的,并在定义的层中使用。

@组件:它是一个基本的自动组件扫描注释,它表示注释类是一个自动扫描组件。

@Controller:带注释的类表示它是一个控制器组件,主要用于表示层。

@服务:它表示带注释的类是业务层中的服务组件。

@存储库:您需要在持久性层中使用此注释,这就像数据库存储库一样。

在注释类时,应该选择一种更专业的@Component形式,因为该注释可能包含未来的特定行为。