ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

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

M
M. Justin

Spring Documentation

@Repository 注释是任何满足存储库角色或原型的类的标记(也称为数据访问对象或 DAO)。此标记的用途之一是异常的自动翻译,如异常翻译中所述。 Spring 提供了更多的原型注解:@Component、@Service 和@Controller。 @Component 是任何 Spring 管理的组件的通用构造型。 @Repository、@Service 和 @Controller 是 @Component 针对更具体的用例(分别在持久层、服务层和表示层)的特化。因此,您可以使用@Component 注释您的组件类,但是通过使用@Repository、@Service 或@Controller 注释它们,您的类更适合工具处理或与方面关联。例如,这些原型注释是切入点的理想目标。 @Repository、@Service 和 @Controller 还可以在 Spring 框架的未来版本中携带额外的语义。因此,如果您在服务层使用@Component 或@Service 之间进行选择,@Service 显然是更好的选择。同样,如前所述,@Repository 已被支持作为持久层中自动异常转换的标记。

注释 含义 @Component 任何 Spring 管理组件的通用原型 @Repository 原型用于持久层 @Service 原型用于服务层 @Controller 原型用于表示层(spring-mvc)


R
Raman Sahasi

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

首先,值得再次强调的第一个相似点是,对于 BeanDefinition 的扫描自动检测和依赖注入,所有这些注释(即,@Component、@Service、@Repository、@Controller)都是相同的。我们可以用一个代替另一个,并且仍然可以解决问题。

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

@零件

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

@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 注解,这意味着它们也是 @Component。如果我们定义自己的自定义注解并使用 @Component 对其进行注解,那么它也将使用 <context:component-scan> 进行扫描

@Repository

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

@Repository 有什么特别之处?

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

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

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

@控制器

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

@Controller 有什么特别之处?

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

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

@服务

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

@Service 有什么特别之处?

除了它用于指示它持有业务逻辑这一事实之外,此注释中没有其他值得注意的地方;但谁知道呢,Spring 将来可能会添加一些额外的异常。

还有什么?

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


奇妙的解释。你解开了我的很多误解。来自一所大学,我们从下到上构建了所有项目,即使您自己没有明确地将程序链接在一起,我也很难理解为什么 Spring Applications 能正常工作。注释现在很有意义,谢谢!
B
Bozho

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

@Controller beans 由 spring-mvc 使用

@Repository bean 有资格进行持久性异常翻译

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

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

例如最近我做了:

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

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


@Component bean 可以被 spring 容器自动检测到。您不需要在配置文件中定义 bean,它会在运行时被 Spring 自动检测到。
O
Oliver

@Component 等价于

<bean>

@Service, @Controller, @Repository = {@Component + 一些更特殊的功能}

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

这三个注释用于分隔应用程序中的“层”,

控制器只是做一些事情,比如调度、转发、调用服务方法等。

服务保持业务逻辑,计算等。

存储库是 DAO(数据访问对象),它们直接访问数据库。

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

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

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

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

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


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

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

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

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

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

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

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

https://i.stack.imgur.com/nXfyV.jpg


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

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 – 表示自动扫描组件。 @Repository - 表示持久层中的 DAO 组件。 @Service – 表示业务层中的服务组件。 @Controller – 表示表示层中的控制器组件。

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


Y
YogendraR

这些是刻板印象注释,可用于自动扫描

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

来自 Spring 源代码:

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

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

每个注释的目的:

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

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

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


W
Wahyu Kristianto

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

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

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


a
atish shimpi

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

H
Harshal Patil

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

如果我们添加@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 注释将存在于类的顶部


S
Saheb

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

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

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

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

@Repository:您需要在持久层中使用此注解,这类似于数据库存储库。

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


I
Ihor Patsian

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

表示持久层组件:@Repository

表示服务层组件:@Service

表示表示层组件:@Controller

否则您可以对所有这些都使用@Component。


I
Ihor Patsian

@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{

你可以通过

CustomerService cust = (CustomerService)context.getBean("AAA");

C
Community

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

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

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

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

春天里的@Component

https://i.stack.imgur.com/FFIdh.png


S
Saheb

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

参考 Spring 现在支持的 JSR-330,您只能使用 @Named 来定义一个 bean(不知何故 @Named=@Component)。所以根据这个标准,似乎没有用为类别 bean 定义构造型(如 @Repository@Service@Controller)。

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

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


M
Manjush

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

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


S
Software Engineer

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

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

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

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

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

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

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


P
Premraj

在 Spring 4 中,最新版本:

@Repository 注释是任何满足存储库角色或原型的类的标记(也称为数据访问对象或 DAO)。此标记的用途之一是异常的自动翻译,如第 20.2.2 节“异常翻译”中所述。 Spring 提供了更多的原型注解:@Component、@Service 和@Controller。 @Component 是任何 Spring 管理的组件的通用构造型。 @Repository、@Service 和 @Controller 是 @Component 针对更具体的用例的特化,例如,分别在持久层、服务层和表示层中。因此,您可以使用@Component 注释您的组件类,但是通过使用@Repository、@Service 或@Controller 来注释它们,您的类更适合工具处理或与方面关联。例如,这些原型注释是切入点的理想目标。在 Spring Framework 的未来版本中,@Repository、@Service 和 @Controller 也可能带有额外的语义。因此,如果您在服务层使用@Component 或@Service 之间进行选择,@Service 显然是更好的选择。同样,如上所述,@Repository 已被支持作为持久层中自动异常转换的标记。


M
Mehraj Malik

@Component 是顶级通用注释,它使带注释的 bean 被扫描并在 DI 容器中可用

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

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

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

这里有更多details


R
Romil Patel

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

@Controller 与 RestController

@RestController:

https://i.stack.imgur.com/U9mP2.png

这个注解是@Controller 的一个特殊版本,它自动添加了@Controller 和@ResponseBody 注解。所以我们不必将@ResponseBody 添加到我们的映射方法中。这意味着 @ResponseBody 默认处于活动状态。

如果您使用@RestController,则无法返回视图(通过在 Spring/Spring-Boot 中使用 Viewresolver)

@RestController 还自动将响应转换为 JSON/XML,因为 @ResponseBody 将返回的对象转换为可能在正文中的内容,例如 JSON 或 XML

@控制器

https://i.stack.imgur.com/BKR7s.png

@Controller 用于将类标记为 Spring MVC 控制器。这个注解只是@Component 的一个特殊版本,它允许基于类路径扫描自动检测控制器类。

@Controller 你可以在 Spring Web MVC 中返回一个视图。

More Detailed View


B
Bharath

@Service 引用 spring 文档,

表示带注释的类是“服务”,最初由域驱动设计(Evans,2003)定义为“作为独立于模型中的接口提供的操作,没有封装状态。”也可能表明一个类是“业务服务外观”(在核心 J2EE 模式意义上),或类似的东西。此注释是通用的刻板印象,各个团队可能会缩小其语义并酌情使用。

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

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

以及根据 Eric Evans 的 Repository

存储库将某种类型的所有对象表示为一个概念集(通常是模拟的)。它就像一个集合,除了具有更精细的查询功能。添加和删除适当类型的对象,存储库后面的机器将它们插入或从数据库中删除。这个定义收集了一组有凝聚力的责任,用于从生命周期的早期到结束提供对 AGGREGATES 根的访问。


M
Maria Pomazkina-Karpikova

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


M
Mykhailo Moskura

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

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

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

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


P
Partho

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之间的区别

https://i.stack.imgur.com/IkRcg.png

@Component vs @Repository vs @Service

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

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

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

@Service 在服务层注释类。

@Repository 在持久层注释类,它将充当数据库存储库。

@Component 注解

@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 的特例。它们在技术上是相同的,但我们将它们用于不同的目的。根据它们的层约定选择注释总是一个好主意。


J
Jeevan Patil

刻板印象的解释:

@Service - 使用 @Service 注释所有服务类。该层知道工作单元。您所有的业务逻辑都将在服务类中。通常,服务层的方法都包含在事务中。您可以从服务方法进行多次 DAO 调用,如果一个事务失败,所有事务都应该回滚。

@Repository - 使用 @Repository 注释所有 DAO 类。您所有的数据库访问逻辑都应该在 DAO 类中。

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

@Autowired - 让 Spring 使用 @Autowired 注解将其他 bean 自动连接到您的类中。

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

最初回答 here


J
Jeef

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

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

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


B
Brajesh

在 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 文件中添加 <context:component-scan> 时,spring 会在上下文创建/加载阶段自动创建带有上述注解的类的对象。


m
menoktaokan

@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 管理器的外观模式(外观)和事务处理


D
Dmitry Rakovets

为了简化这个说明,让我们根据用例考虑技术性,这些注释用于注入,正如我所说的字面意思“用于注入”,这意味着,如果你知道如何使用依赖注入“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 都是 @Component 的特例,然而,组件的常见用例是当您制作纯技术而不是直接业务案例时!比如格式化日期或者处理特殊请求序列化机制等等。


I
IndexOutOfDevelopersException
@Component
@Controller
@Repository
@Service
@RestController

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