Spring中的@Component、@Repository和@Service注解有啥区别?

Posted

技术标签:

【中文标题】Spring中的@Component、@Repository和@Service注解有啥区别?【英文标题】:What's the difference between @Component, @Repository & @Service annotations in Spring?Spring中的@Component、@Repository和@Service注解有什么区别? 【发布时间】:2011-10-13 06:05:43 【问题描述】:

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

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

或者注解也会影响类的行为和功能?

【问题讨论】:

作为一名拥有微软背景的开发人员,我想起了旧的 MS SmartClientSoftwareFactory 框架(现在是分布式桌面应用程序长期弃用的复杂框架)中服务的语义定义。该定义(Rich Newman 的nicely documented)将服务定义为无状态的可重用对象,最好具有单例范围,用于对作为参数传递的其他对象执行业务逻辑操作。我倾向于以同样的方式查看 Spring 服务 没关系!!不管对你有用:) 我一直讨厌 Spring 的这一点,他们总是倾向于为你定义“规则”,这只会为你的应用程序增加微不足道的价值。更不用说 Spring 自带了巨大的堆栈。 @TriCore Sprting 是一个框架,为你定义“规则”是它的工作:) 【参考方案1】:

来自Spring Documentation:

@Repository 注释是任何满足 存储库的角色或原型(也称为数据访问对象) 或 DAO)。该标记的用途之一是自动翻译 例外,如Exception Translation 中所述。

Spring 提供了更多的原型注解:@Component@Service、 和@Controller@Component 是任何一个通用的刻板印象 Spring 管理的组件。 @Repository@Service@Controller@Component 的专业化用于更具体的用例(在 分别是持久层、服务层和表示层)。 因此,您可以使用@Component 注释您的组件类, 但是,通过使用 @Repository@Service@Controller 注释它们 相反,您的类更适合工具处理 或与方面相关联。

例如,这些原型注解 为切入点制作理想的目标。 @Repository@Service@Controller 还可以在未来的版本中携带额外的语义 春天框架。因此,如果您在使用 @Component@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)

【讨论】:

【参考方案2】:

由于许多答案已经说明了这些注释的用途,因此我们将在此重点介绍它们之间的一些细微差别。

首先是相似度

值得再次强调的第一点是关于 BeanDefinition 的扫描自动检测和依赖注入所有这些注释(即,@Component、@Service、 @Repository, @Controller) 是一样的。 我们可以就地使用一个 另一个,仍然可以解决我们的问题。


@Component、@Repository、@Controller 和@Service 的区别

@Component

这是一个通用的原型注解,表明该类是一个弹簧组件。

@Component 有什么特别之处<context:component-scan> 只扫描@Component 而不会在其中查找@Controller@Service@Repository一般的。它们被扫描是因为它们本身带有 @Component 注释。

看看@Controller@Service@Repository注解定义:

@Component
public @interface Service 
    ….

 

@Component
public @interface Repository 
    ….

 

@Component
public @interface Controller 
    …

因此,说@Controller@Service@Repository@Component注解的特殊类型并没有错。 <context:component-scan> 拾取它们并将它们的以下类注册为 bean,就好像它们被 @Component 注释一样。

特殊类型的注解也会被扫描,因为它们本身带有@Component注解,也就是说它们也是@Components。如果我们定义自己的自定义注解并使用@Component 进行注解,它也会被<context:component-scan> 扫描


@Repository

这是表示该类定义了一个数据存储库。

@Repository 有什么特别之处?

除了指出这是一个基于注解的配置之外,@Repository 的工作是捕获特定于平台的异常并将它们作为 Spring 的统一未检查异常之一重新抛出。为此,我们提供了PersistenceExceptionTranslationPostProcessor,我们需要将其添加到 Spring 的应用程序上下文中,如下所示:

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

此 bean 后处理器向任何带有 @Repository 注释的 bean 添加一个顾问,以便捕获任何特定于平台的异常,然后作为 Spring 的未经检查的数据访问异常之一重新抛出。


@Controller

@Controller 注释表示特定类充当控制器的角色。 @Controller 注释充当被注释类的构造型,指示其角色。

@Controller 有什么特别之处?

我们不能将此注释与@Service@Repository 之类的任何其他注释进行切换,即使它们看起来相同。 调度程序扫描带有@Controller 注释的类并检测其中带有@RequestMapping 注释的方法。我们只能在其类使用@Controller 注释的方法上/在其中使用@RequestMapping,并且它适用于@Component@Service@Repository 等... p>

注意:如果一个类已经通过任何替代方法注册为 bean,例如通过@Bean 或通过@Component@Service 等...注解,那么@RequestMapping 可以如果该类也使用@RequestMapping 注释进行注释,则选择该类。但那是另一种情况。


@Service

@Service bean 在存储库层中保存业务逻辑和调用方法。

@Service 有什么特别之处?

除了它用来表示,它持有业务逻辑之外,这个注解中没有其他值得注意的地方;但谁知道呢,Spring 将来可能会添加一些额外的例外。


还有什么?

与上述类似,未来 Spring 可能会根据它们的分层约定为 @Service@Controller@Repository 添加特殊功能。因此,尊重约定并根据层使用它始终是一个好主意。

【讨论】:

奇妙的解释。你解开了我的很多误解。来自一所大学,我们从下到上构建了所​​有项目,即使您自己没有明确地将程序链接在一起,我也很难理解为什么 Spring Applications 能正常工作。注释现在很有意义,谢谢! @Raman Sahasi 很好的解释。感谢分享。【参考方案3】:

它们几乎相同——它们都意味着该类是一个 Spring bean。 @Service@Repository@Controller 是专门的 @Components。您可以选择对它们执行特定操作。例如:

@Controller bean 被 spring-mvc 使用 @Repository bean 有资格进行持久性异常翻译

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

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

比如我最近做的:

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

所以所有用@ScheduledJob 注释的类都是spring beans,除此之外还注册为quartz 作业。您只需提供处理特定注释的代码。

【讨论】:

@Component beans 可以被 spring 容器自动检测到。不需要在配置文件中定义bean,Spring会在运行时自动检测到。【参考方案4】:

@Component 等价于

<bean>

@Service、@Controller、@Repository = @Component + 一些更特殊的功能

这意味着服务、控制器和存储库在功能上是相同的。

这三个注解用于在你的应用中分隔“Layers”

控制器只做调度、转发、调用服务方法等工作。 Service Hold 业务逻辑、计算等 存储库是 DAO(数据访问对象),它们直接访问数据库。

现在你可能会问为什么要分开它们:(我假设你知道 AOP-Aspect Oriented Programming)

假设您只想监控 DAO 层的活动。您将编写一个 Aspect(A 类)类,该类在调用 DAO 的每个方法之前和之后进行一些日志记录,您可以使用 AOP 来做到这一点,因为您拥有三个不同的层并且不混合。

因此,您可以在 DAO 方法“周围”、“之前”或“之后”记录 DAO。你可以这样做,因为你一开始就有一个 DAO。您刚刚实现的是关注点或任务的分离。

试想如果@Controller只有一个注解,那么这个组件的调度、业务逻辑和访问数据库都是混在一起的,这么脏的代码!

上面提到的是一个很常见的场景,为什么要使用三个注解还有很多用例。

【讨论】:

我有一个基本问题 - 是弹簧机制使用的注释还是只是为了让程序员记住这些代码的作用? @user107986 它们主要是为了让程序员记住应用程序中的层。不过@Respository 也有自动异常翻译功能。就像在@Repository 中发生异常时一样,通常有一个处理该异常的处理程序,并且不需要在 DAO 类中添加 try catch 块。它与 PersistenceExceptionTranslationPostProcessor 一起使用【参考方案5】:

在 Spring 中,@Component@Service@Controller@Repository 是用于:

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

@Service:所有业务逻辑都在这里,即数据相关的计算和所有。业务层的这个注解,我们的用户不直接调用持久化方法,所以它会使用这个注解调用这个方法。 它将根据用户请求请求@Repository

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

@Component - 使用组件构造型注释您的其他组件(例如 REST 资源类)。

表示带注释的类是“component”。这样的类是 使用时被视为自动检测的候选者 基于注释的配置和类路径扫描。

其他类级别的注释可以被认为是标识一个 组件也是如此,通常是一种特殊类型的组件:例如这 @Repository 注解或 AspectJ 的 @Aspect 注解。

【讨论】:

这些答案都很好,但我很确定我们大多数人想要的是一些代码示例,这些示例是服务等组件提供的功能的一些代码示例,我们可以更具体地放在我们的脑海中,而不仅仅是一般像“业务逻辑”这样的描述属于这个对象。否则,我们仍然假设“哦,这很好,但我仍然可以将相同的代码应用于组件”【参考方案6】:

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

@Component – Indicates a auto scan component.
@Repository – Indicates DAO component in the persistence layer.
@Service – Indicates a Service component in the business layer.
@Controller – Indicates a controller component in the presentation layer.

参考:-Spring Documentation - Classpath scanning, managed components and writing configurations using Java

【讨论】:

【参考方案7】:

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

来自 Spring 源代码:

表明一个带注释的类是一个“组件”。在使用基于注释的配置和类路径扫描时,此类类被视为自动检测的候选对象。

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

每个注释的用途:

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

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

使用三个不同的@annotations 的主要目的是为企业应用程序提供更好的模块化。

【讨论】:

【参考方案8】:

从数据库连接的角度来看,@Service@Repository 注释的使用很重要。

    对所有 Web 服务类型的数据库连接使用 @Service 对所有存储的 proc DB 连接使用 @Repository

如果您没有使用正确的注解,您可能会面临被回滚事务覆盖的提交异常。您将在压力负载测试期间看到与回滚 JDBC 事务相关的异常。

【讨论】:

【参考方案9】:

@Repository @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.

【讨论】:

【参考方案10】:

所有这些注解都是立体类型的注解类型,这三个注解的区别是

如果我们添加@Component 那么它告诉类的角色是一个组件类这意味着它是一个包含一些逻辑的类,但是它 不知道一个类是否包含特定的业务或 持久性或控制器逻辑,所以我们不直接使用它 @Component 注解 如果我们添加@Service注解,那么它告诉我们一个类的角色组成业务逻辑 如果我们在类顶部添加@Repository,那么它会告诉我们一个包含持久性逻辑的类 这里的@Component 是@Service、@Repository 和@Controller 注解的基础注解

例如

package com.spring.anno;
@Service
public class TestBean

    public void m1()
    
       //business code
    


package com.spring.anno;
@Repository
public class TestBean

    public void update()
    
       //persistence code
    

每当我们添加 @Service@Repositroy@Controller 注释时,默认情况下 @Component 注释将存在于类之上

【讨论】:

【参考方案11】:

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

@Component:是基本的自动组件扫描注解,表示被注解的类是自动扫描组件。

@Controller:注解类表示它是一个控制器组件,主要用在表现层。

@Service:表示注解类是业务层的Service组件。

@Repository:你需要在持久层中使用这个注解,这就像数据库存储库。

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

【讨论】:

【参考方案12】:

@Component@Service@Controller@Repository 之间没有区别。 @Component 是表示我们 MVC 组件的通用注解。但是会有几个组件作为我们的 MVC 应用程序的一部分,例如服务层组件、持久层组件和表示层组件。因此,为了区分它们,Spring 人们也给出了其他三个注释。

表示持久层组件:@Repository 表示服务层组件:@Service 表示表示层组件:@Controller 否则您可以使用@Component 来处理所有这些问题。

【讨论】:

【参考方案13】:

使用@Component 注释其他组件,例如 REST 资源类。

@Component
public class AdressComp
    .......
    ...//some code here    

@Component 是任何 Spring 托管组件的通用构造型。

@Controller、@Service 和 @Repository 是 @Component 针对特定用例的特化。

@Spring 中的组件

【讨论】:

【参考方案14】:

我们可以根据java标准来回答这个问题

参考JSR-330,现在spring已经支持了,只能用@Named来定义一个bean(不知怎么@Named=@Component)。所以根据这个标准,似乎没有用为类别bean定义原型(如@Repository@Service@Controller)。

但是spring用户这些不同的注解在不同的具体用途中,例如:

    帮助开发人员为胜任者定义更好的类别。在某些情况下,这种分类可能会有所帮助。 (例如,当您使用aspect-oriented 时,这些可能是pointcuts 的良好候选者) @Repository 注释将为您的 bean 添加一些功能(一些自动异常转换到您的 bean 持久层)。 如果你使用的是spring MVC,@RequestMapping只能添加到@Controller注解的类中。

【讨论】:

【参考方案15】:

@Component:你注释了一个类@Component,它告诉hibernate它是一个Bean。

@Repository:你注解了一个类@Repository,它告诉hibernate它是一个DAO类,并把它当作DAO类。意味着它使未经检查的异常(从 DAO 方法抛出)有资格转换为 Spring DataAccessException

@Service:这告诉 hibernate 它是一个服务类,您将在其中拥有@Transactional 等服务层注释,因此 hibernate 将其视为一个服务组件。

加上@Service@Component 的高级。假设bean类名是CustomerService,因为你没有选择XML bean配置方式所以你用@Component注解了bean,表示它是一个Bean。因此,在获取 bean 对象 CustomerService cust = (CustomerService)context.getBean("customerService"); 时,默认情况下,Spring 会将组件的第一个字符小写——从“CustomerService”到“customerService”。您可以检索名为“customerService”的组件。 但是如果你对 bean 类使用 @Service 注解,你可以通过

提供一个特定的 bean 名称
@Service("AAA")
public class CustomerService

你可以通过

获取bean对象
CustomerService cust = (CustomerService)context.getBean("AAA");

【讨论】:

【参考方案16】:

即使我们交换 @Component 或 @Repository 或 @service

它的行为是相同的,但一方面是如果我们使用组件或@service,它们将无法捕获与 DAO 而不是 Repository 相关的某些特定异常

【讨论】:

【参考方案17】:

这里提供的答案在技术上是部分正确的,但是即使响应列表很长而且这将在底部,我认为也值得在此处放置一个真正正确的响应,以防万一有人偶然发现它并学习从中获得有价值的东西。不是其余的答案完全错误,只是他们不正确。而且,为了阻止成群的巨魔,是的,我知道从技术上讲,这些注释现在实际上是相同的东西,甚至在春季 5 之前大部分都可以互换。现在,为了正确答案:

这三个注解是完全不同的东西,不能互换。你可以说出来,因为它们是三个而不是一个。它们的目的不是可互换的,它们只是为了优雅和方便而以这种方式实现的。

现代编程是各种比例的发明、艺术、技术和交流。通信位通常非常重要,因为代码的读取频率通常比写入的频率高得多。作为程序员,您不仅要尝试解决技术问题,还要尝试将您的意图传达给阅读您代码的未来程序员。这些程序员可能不会分享你的母语,也不会分享你的社交环境,而且他们可能会在 50 年后阅读你的代码(这并不像你想象的那么不可能)。在遥远的未来,很难有效地沟通。因此,使用我们可用的最清晰、最有效、正确和交流的语言至关重要。我们谨慎选择措辞以产生最大影响并尽可能清楚地表达我们的意图。

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

我不会深入其他示例,但会尽可能清楚地说明:这些注释是完全不同的东西,应该根据它们的意图适当地使用它们。 @Repository 用于存储库,没有其他注释是正确的。 @Service 用于服务,没有其他注释是正确的。 @Component 用于既不是存储库也不是服务的组件,使用其中任何一个代替它也是不正确的。它可能会编译,甚至可能运行并通过您的测试,但这是错误的,如果您这样做,我会(专业地)少考虑您。

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

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

【讨论】:

【参考方案18】:

在 Spring 4 中,最新版本:

@Repository 注释是任何满足 存储库的角色或原型(也称为数据访问对象) 或 DAO)。该标记的用途之一是自动翻译 第 20.2.2 节“异常转换”中描述的异常。

Spring 提供了更多的原型注解:@Component、@Service、 和@Controller。 @Component 是任何类型的通用构造型 Spring 管理的组件。 @Repository、@Service 和 @Controller 是 @Component 的专业化用于更具体的用例,例如 例如,在持久层、服务层和表示层中, 分别。因此,您可以使用注释您的组件类 @Component,但通过使用 @Repository、@Service 或 @Controller 相反,您的类更适合 通过工具处理或与方面相关联。例如,这些 原型注释是切入点的理想目标。也是 @Repository、@Service 和 @Controller 可能携带 Spring Framework 未来版本中的附加语义。因此, 如果您在使用 @Component 或 @Service 之间进行选择 服务层,@Service 显然是更好的选择。同样,作为 如上所述,@Repository 已被支持作为标记 持久层中的自动异常转换。

【讨论】:

【参考方案19】:

@Component 是***通用注解,它使被注解的 bean 被扫描并在 DI 容器中可用

@Repository 是专门的注解,它带来了从 DAO 类中转换所有未经检查的异常的特性

@Service 是专门的注解。到目前为止,它没有带来任何新功能,但它阐明了 bean 的意图

@Controller 是专门的注解,它使 bean MVC 感知并允许使用进一步的注解,如 @RequestMapping 和所有此类

这里有更多details

【讨论】:

【参考方案20】:

这里有足够好的答案来解释组件存储库服务注释之间的区别。我想分享@Controller &amp; @RestController之间的区别

@Controller vs RestController

@RestController

此注解是@Controller 的专用版本,它添加了 @Controller@ResponseBody 自动注解。所以我们不必将@ResponseBody 添加到我们的映射方法中。这意味着 @ResponseBody 默认激活。 如果您使用@RestController,您将无法返回视图(通过使用 Viewresolver 在 Spring/Spring-Boot 中) @RestController 还将响应转换为 JSON/XML automatically,因为 @ResponseBody 使返回的对象成为可能在正文中的对象,e.g. JSON or XML

@Controller

@Controller 用于将类标记为 Spring MVC 控制器。这 注释只是@Component 的一个特殊版本,它 允许根据类路径自动检测控制器类 扫描。 @Controller 你可以在 Spring Web MVC 中返回一个视图。

More Detailed View

【讨论】:

【参考方案21】:

@Service 引用 spring 文档,

表明一个带注释的类是一个“服务”,最初定义 由领域驱动设计 (Evans, 2003) 描述为“作为 在模型中独立存在的接口,没有封装状态。” 也可以表明一个类是一个“业务服务门面”(在 核心 J2EE 模式感觉)或类似的东西。这个注解是 通用的刻板印象和个别团队可能会缩小他们的 语义并酌情使用。

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

SERVICE 是作为独立于 模型,没有封装状态,作为实体和值对象 做。 SERVICES 是技术框架中的一种常见模式,但它们 也可以应用在领域层。名称服务强调 与其他对象的关系。与实体和价值对象不同,它 纯粹是根据它可以为客户做什么来定义的。一项服务 倾向于以活动命名,而不是实体——动词而不是实体 比名词。一个服务仍然可以有一个抽象的、有意的 定义;它只是具有与定义不同的风味 目的。 SERVICE 仍应有明确的职责,并且 职责和实现它的接口应定义为 域模型的一部分。操作名称应来自 UBIQUITOUS LANGUAGE 或被引入其中。参数和结果 应该是域对象。应该明智地使用服务,而不是 允许剥离其所有行为的实体和价值对象。 但是当一个操作实际上是一个重要的领域概念时,一个 服务是模型驱动设计的自然组成部分。在宣布 模型作为服务,而不是作为不 实际上代表什么,独立操作不会误导 任何人。

还有一个 Repository 根据 Eric Evans,

存储库将某种类型的所有对象表示为概念 设置(通常是模拟的)。它就像一个集合,除了更多 精细的查询能力。适当类型的对象是 添加和删​​除,以及 REPOSITORY 后面的机器插入 它们或从数据库中删除它们。这个定义收集了一个 提供访问根目录的一系列责任 从生命周期的早期到结束的汇总。

【讨论】:

【参考方案22】:

RepositoryServiceComponent 注释的子级。所以,它们都是组件RepositoryService 只是扩展它。 具体如何? 服务只有意识形态上的区别:我们将其用于服务。 Repository 有特定的异常处理程序。

【讨论】:

【参考方案23】:

刻板印象的解释:

@Service - 使用 @Service 注释所有服务类。该层知道工作单元。您所有的业务逻辑都将在服务类中。通常,服务层的方法都包含在事务中。您可以从服务方法进行多次 DAO 调用,如果一个事务失败,所有事务都应该回滚。 @Repository - 使用 @Repository 注释所有 DAO 类。您所有的数据库访问逻辑都应该在 DAO 类中。 @Component - 使用组件构造型注释您的其他组件(例如 REST 资源类)。 @Autowired - 让 Spring 使用 @Autowired 注解将其他 bean 自动连接到您的类中。

@Component 是任何 Spring 管理组件的通用构造型。 @Repository@Service@Controller@Component 的特化,用于更具体的用例,例如,分别在持久层、服务层和表示层中。

最初回答here。

【讨论】:

【参考方案24】:

@Component、@Repository、@Controller 和 @Service 注释之间的区别

@Component – 通用,可跨应用程序使用。 @Service – 在服务层级别注释类。 @Controller – 注释 表示层级别的类,主要用于 Spring MVC。 @Repository - 在持久层注释类,它将充当 数据库存储库。

@Controller = @Component(内部注释)+ 表示层功能 @Service = @Component(内部注释)+ 服务层功能@Component = 实际组件(Bean)@ 987654324@ = @Component(内部注释)+ 数据层功能(用于处理域 Bean)

【讨论】:

【参考方案25】:

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

@Service,扩展@Component注解,只是命名不同。

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

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

【讨论】:

【参考方案26】:

在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.

上面声明的注解是特殊的,因为当我们在 xxx-servlet.xml 文件中添加&lt;context:component-scan&gt; 时,spring 会在上下文创建/加载阶段自动创建那些被上面注解注解的类的对象。

【讨论】:

【参考方案27】:

@Component@ Repository@ Service@Controller

@Component 是 Spring 管理的组件的通用构造型 @Repository@Service@Controller 是用于更具体用途的 @Component 特化:

@Repository 坚持不懈 @Service 用于服务和交易 @Controller 用于 MVC 控制器

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

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

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

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

【讨论】:

【参考方案28】:

Spring 支持@Component、@service、@Repository 等多种类型的注解。所有这些都可以在 org.springframework.stereotype 包下找到,@Bean 可以在 org.springframework.context.annotation 包下找到。

当我们的应用程序中的类使用上述任何注释进行注释时,然后在项目启动期间弹簧扫描(使用@ComponentScan)每个类并将类的实例注入 IOC 容器。 @ComponentScan 会做的另一件事是运行带有 @Bean 的方法并将返回对象作为 bean 恢复到 Ioc 容器。

在我们深入研究(@Component vs @service vs @Repository)之前,最好先了解@Bean 和@Component 之间的区别


@Component vs @Repository vs @Service


在大多数典型应用程序中,我们有不同的层,如数据访问、表示、服务、业务等。此外,在每一层中,我们都有不同的 bean。为了自动检测这些 bean,Spring 使用类路径扫描注解。然后在 ApplicationContext 中注册每个 bean。

以下是其中一些注释的简短概述:

@Component 是任何 Spring 管理的组件的通用构造型。 @Service 在服务层注释类。 @Repository 在持久层注释类,它将充当数据库存储库。

@组件注解

@Component 是一个类级别的注解。我们可以在整个应用程序中使用@Component 将bean 标记为Spring 的托管组件。 Spring 只会用@Component 获取和注册bean,一般不会查找@Service 和@Repository。

它们在 ApplicationContext 中注册,因为它们带有 @Component 注释

如上所述,@Component 是所有原型注释的父级。当 Spring 执行组件扫描时,它只查找标有 @Component 注解的类。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component 
    String value() default "";

我们可以在所有类上使用这个注解,不会造成任何差异。

@Service 注解

我们用@Service 标记bean 以表明它们持有业务逻辑。这个注解除了用在服务层,没有其他特殊用途。

@Service 是组件的子组件,用于表示来自应用程序服务层的类。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service 
   @AliasFor(
       annotation = Component.class
   )
   String value() default "";

@Repository 注释

@Repository 的工作是捕获特定于持久性的异常并将它们作为 Spring 统一的未检查异常之一重新抛出。

为此,Spring 提供了 PersistenceExceptionTranslationPostProcessor,我们需要将其添加到应用程序上下文中(如果我们使用 Spring Boot,则已包含):

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

此 bean 后处理器向任何使用 @Repository 注释的 bean 添加顾问。

同样,@Repository 也是组件注解的子类,用于属于持久化数据访问层的类,作为数据存储库。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository 
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";

总结

@Service 和@Repository 是@Component 的特例。它们在技术上是相同的,但我们将它们用于不同的目的。根据它们的层约定选择注释总是一个好主意。

【讨论】:

【参考方案29】:

为了简化这个说明,让我们通过用例来考虑技术性,这些注解用于注入,正如我所说的字面意思“用于注入”,也就是说,如果你知道如何使用 Dependency Injection "DI" 并且您应该,然后您将始终寻找这些注释,并且通过使用这些 Stereo Types 注释类,您将通知 DI 容器扫描它们以准备在其他地方注入,这是实际的目标。

现在让我们移到每一个;首先@Service,如果您正在为特定的业务案例构建一些逻辑,您需要将其分隔在一个包含您的业务逻辑的地方,该服务是普通类,或者您可以根据需要将其用作接口,并且它是写的像这样

@Service
public class Doer 
   // Your logic 

要在另一个类中使用它,假设在 Controller 中

@Controller
public class XController 
    // You have to inject it like this 
    @Autowired 
    private Doer doer;

    // Your logic

注入它们的方式都是一样的,@Repository 这是一个应用Repository Pattern实现的接口Repository design pattern,通常用于处理一些数据存储或数据库,你会发现,它包含多个现成的实现供你处理数据库操作;可以是CrudRepositoryJpaRepository 等。

例如:

public interface DoerRepository implements JpaRepository<Long, XEntity> 

最后是@Component,这是Spring中注册bean的通用形式,也就是spring一直在寻找标有@Component的bean进行注册,那么@Service@Repository都是@的特例987654333@,但是组件的常见用例是当您制作纯技术而不是直接业务案例时!比如格式化日期或者处理特殊请求序列化机制等等。

【讨论】:

【参考方案30】:
@Component
@Controller
@Repository
@Service
@RestController

这些都是 StereoType 注释。这对于将我们的类作为 ioc 容器中的 spring bean 很有用,

【讨论】:

以上是关于Spring中的@Component、@Repository和@Service注解有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 希望 @Component 类成为 @Configuration 类中的 @Bean

@Component——标注一个类为Spring容器的Bean

@Bean 和 @Component 注释是不是相同但针对 Spring Framework 中的不同目标? [复制]

spring中@Component注解

[刘阳Java]_Spring常用注解介绍_第6讲

spring @component的作用