Spring中的@ Component,@ Repository和@Service注释有什么区别?

Col*_*ree 1969 java spring annotations spring-mvc

@Component,@Repository@Service注释互换在Spring中,还是他们提供任何特殊的功能,除了作为一个符号设备?

换句话说,如果我有一个Service类并且我将注释更改@Service@Component,它仍然会以相同的方式运行吗?

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

sti*_*vlo 1430

Spring文档:

在Spring 2.0及更高版本中,@Repository注释是任何满足存储库的角色或构造型(也称为数据访问对象或DAO)的类的标记.该标记的用途包括异常的自动转换.

Spring 2.5中引入了进一步典型化注解:@Component, @Service,和@Controller.@Component是任何Spring管理组件的通用构造型.@Repository,@Service和,并且@Controller@Component更具体的用例的特化,例如,分别在持久性,服务和表示层中.

因此,你可以用你的注解组件类@Component,但如果用注解它们@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)      ?
????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

  • 它指的是这些注释是AOP的良好目标,而其他注释尚未定义切入点,他们可能会在未来这样做.另一方面,@ Repository目前已成为切入点的目标.该切入点用于异常转换,即将特定于技术的异常转换为更通用的基于Spring的异常,以避免紧密耦合. (9认同)
  • 将@Controller(或@Component)添加到@WebServlet是否有意义?它不是Spring MVC控制器,但这是概念上最接近的匹配.那么servlet过滤器呢? (6认同)
  • 我是否正确理解,截至今天,`@Component`、`@Service` 和 `@Repository` 之间没有功能差异,除了后一种情况下的异常转换之外? (5认同)
  • @stivlo:我真的试图理解"刻板印象"一词,但仍然不明白.你能帮我理解这个术语吗?它非常有帮助,非常感谢你 (3认同)
  • http://stackoverflow.com/questions/14756486/what-is-a-spring-stereotype (3认同)
  • @xenoterracide*实际上*没有太大区别.用@@ Service`*注释的东西也是@ @ Component`(因为`@Service`注释本身用`@Component`注释).据我所知,Spring框架中没有任何内容明确地使用了某个东西是`@Service`的事实,所以差异实际上只是概念性的. (2认同)

Ram*_*asi 728

由于许多答案已经说明了这些注释的用途,我们将在这里集中讨论它们之间的一些细微差别.

首先是相似性

值得再次强调的第一点是,对于BeanDefinition的扫描自动检测和依赖注入,所有这些注释(即@ Component,@ Service,@ Repository,@ Controller)都是相同的.我们可以使用一个代替另一个,仍然可以绕过我们的路.


@ Component,@ Repository,@ Controller和@Service之间的差异

@零件

这是一个通用的构造型注释,表明该类是一个spring组件.

@Component的特殊之处
<context:component-scan>仅在于扫描@Component并且不会查找@Controller,@Service并且@Repository一般而言.扫描它们是因为它们本身都带有注释@Component.

只要看一看@Controller,@Service@Repository注释的定义:

@Component
public @interface Service {
    ….
}
Run Code Online (Sandbox Code Playgroud)

 

@Component
public @interface Repository {
    ….
}
Run Code Online (Sandbox Code Playgroud)

 

@Component
public @interface Controller {
    …
}
Run Code Online (Sandbox Code Playgroud)

因此,说这是没有错的@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"/>
Run Code Online (Sandbox Code Playgroud)

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


@Controller

@Controller注解表明特定类供应控制器的作用.该@Controller注释充当注解类刻板印象,这表明它的作用.

@Controller有什么特别之处?

我们不能与任何其他关掉这个注解像@Service或者@Repository,即使他们看起来一样.调度程序扫描带注释的类@Controller并检测其中的@RequestMapping注释.我们只能使用@RequestMappingon/on注释的类@Controller.


@服务

@Component beans在存储库层中保存业务逻辑和调用方法.

@Service有什么特别之处?

除了它用于表示它保持业务逻辑的事实之外,这个注释中没有其他任何值得注意的东西; 但谁知道,Spring可能会在未来增加一些特殊功能.


还有什么?

与上述类似,在Spring将来可能会增加对特殊功能@Service,@Repository@Bean根据他们的分层约定.因此,尊重约定并将其与层一致使用始终是一个好主意.

  • 神奇的解释.你已经解决了很多我的误解.来自我们自下而上构建所有项目的大学,我很难理解Spring Applications为什么能够正常工作,即使你没有明确地将程序连接在一起.这些注释现在很有意义,谢谢! (10认同)

Boz*_*zho 422

它们几乎相同 - 所有这些都意味着该类是一个Spring bean.@Service,@Repository@Controller有专门的@Component秒.您可以选择使用它们执行特定操作.例如:

  • @Controller spring-mvc使用bean
  • @Repository bean有资格进行持久性异常转换

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

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

例如最近我做了:

@Component
@Scope("prototype")
public @interface ScheduledJob {..}
Run Code Online (Sandbox Code Playgroud)

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

  • 弹簧容器可以自动检测@Component bean.您不需要在配置文件中定义bean,它将在运行时由Spring自动检测. (21认同)

Oli*_*ver 355

@Component相当于

<bean>
Run Code Online (Sandbox Code Playgroud)

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

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

这三个注释用于分离应用程序中的"图层",

  • 控制器只是执行调度,转发,调用服务方法等操作.
  • 服务保持业务逻辑,计算等.
  • 存储库是DAO(数据访问对象),它们直接访问数据库.

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

假设您只想监视DAO层的活动.您将编写一个Aspect(A类)类,在调用DAO的每个方法之前和之后执行一些日志记录,您可以使用AOP执行此操作,因为您有三个不同的层并且不会混合.

因此,您可以在DAO方法"周围","之前"或"之后"记录DAO.你可以这样做,因为你首先有一个DAO.您刚刚实现的是分离关注点或任务.

想象一下,如果只有一个注释@Controller,那么这个组件将具有调度,业务逻辑和访问数据库所有混合,所以脏代码!

上面提到的是一个非常常见的场景,为什么要使用三个注释有更多的用例.

  • @ user107986它们主要供程序员记住应用程序中的图层.但是`@Redpository`也有自动异常转换功能.就像在`@Repository`中发生异常时一样,通常有一个该异常的处理程序,并且不需要在DAO类中添加try catch块.它与PersistenceExceptionTranslationPostProcessor一起使用 (22认同)
  • 我有一个基本问题 - 弹簧机制使用的注释还是程序员只记住这些代码的作用? (6认同)

Har*_*til 218

在春天@Component,@Service,@Controller,和@Repository是它们用于典型化注解:

@Controller:您的请求 从表示页面映射完成,即表示层不会转到任何其他文件,它直接进入@Controller类并检查@RequestMapping在方法调用之前写入的注释中的请求路径(如有必要).

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

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

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

表示带注释的类是" 组件 ".当使用基于注释的配置和类路径扫描时,这些类被视为自动检测的候选者.

其他类级注释也可以被视为标识组件,通常是一种特殊的组件:例如@Repository注释或AspectJ的@Aspect注释.

在此输入图像描述

  • 这些答案都很好,但我非常清楚我们大多数人想要的是一些代码示例,其中包括服务提供的组件,我们可以更具体地放在我们的头脑中,而不仅仅是像"业务逻辑"这样的一般描述属于这个对象.否则,我们仍然假设"哦,这很好,除了我仍然可以将相同的代码应用于组件" (24认同)
  • @HarshalPatil你当然可以在服务中编写一个包含所有业务逻辑的应用程序,但这会导致一个贫乏的域模型,这将使​​得在实体上强制执行约束和一致性变得不必要. (4认同)
  • 不是*所有*业务逻辑都应该进入服务!就DDD而言,服务应仅包含影响多个实体的域逻辑.请参阅答案http://stackoverflow.com/a/41358034/238134 (2认同)

Aji*_*ngh 72

Spring 2.5引入了更多的构造型注释:@ Component,@ Service和@Controller.@Component作为任何Spring管理组件的通用构造型; 而@Repository,@ Service和@Controller用作更具体用例的@Component的特化(例如,分别在持久性,服务和表示层中).这意味着您可以使用@Component注释组件类,但是通过使用@ Repository,@ Service或@Controller注释它们,您的类更适合通过工具处理或与方面相关联.例如,这些刻板印象注释成为切入点的理想目标.当然,在Spring Framework的未来版本中,@ Repository,@ Service和@Controller也可能带有额外的语义.因此,如果您在为服务层使用@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.
Run Code Online (Sandbox Code Playgroud)

参考: - Spring文档 - 使用Java进行类路径扫描,托管组件和编写配置


小智 46

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

  1. 使用@Service的数据库连接的所有Web服务类型
  2. 使用@Repository您的所有存储过程DB连接

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


Yog*_*raR 42

从技术上讲,@ Controller,@ Service,@ Repository都是一样的.所有这些都扩展了@Components.

来自Spring源代码:

表示带注释的类是"组件".当使用基于注释的配置和类路径扫描时,这些类被视为自动检测的候选者.

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

每个注释的目的:

1)@Controller - >用此注释的类,旨在接收来自客户端的请求.第一个请求来到Dispatcher Servlet,它使用@RequestMapping注释的值将请求传递给特定控制器.

2)@Service - >用此注释的类,用于操作我们从客户端接收或从数据库中获取的数据.所有数据操作都应该在这一层完成.

3)@Repository - >用此注释的类,旨在与数据库连接.它也可以被视为DAO(数据访问对象)层.此层应仅限于CRUD(创建,检索,更新,删除)操作.如果需要任何操作,则应将数据发送回@Service层.

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

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


ati*_*mpi 28

@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.
Run Code Online (Sandbox Code Playgroud)


Ani*_*ane 27

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

  • 如果我们添加@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
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 每当我们默认添加@Serviceor @Repositroy@Controllerannotation时,@Component注释就会存在于类的顶部


小智 23

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

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

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

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

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

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


Ali*_*ahi 20

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

引用JSR-330,现在由spring支持,您只能用于@Named定义bean(不知何故@Named=@Component).所以,按照这一标准,似乎是没有用定义定型(如@Repository,@Service,@Controller),以类别豆类.

但是弹簧用户可以根据具体用途使用不同的注释,例如:

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


Ani*_*rgi 19

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

@Component
public class AdressComp{
    .......
    ...//some code here    
}
Run Code Online (Sandbox Code Playgroud)

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

@ Controller,@ Service和@Repository是特定用例的@Component的特化.

@Component in Spring


小智 17

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

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


Qua*_*yen 16

在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作为持久层中自动异常转换的标记.


Par*_*tho 15

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

\n

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

\n

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

\n

在此输入图像描述

\n
\n

@Component vs @Repository vs @Service

\n
\n

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

\n

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

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

@Component注解

\n

@Component是类级别的注释。我们可以在应用程序中使用@Component将bean标记为Spring的托管组件。Spring只会使用@Component来获取和注册bean,并且通常不会查找@Service和@Repository。

\n

它们被注册在ApplicationContext中,因为它们被@Component注解

\n

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

\n
@Target({ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Indexed\npublic @interface Component {\n    String value() default "";\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我们可以在所有类上使用这个注释,它不会导致任何差异。

\n

@Service注解

\n

我们用 @Service 标记 bean,以表明它们持有业务逻辑。除了在服务层使用之外,该注释没有任何其他特殊用途。

\n

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

\n
@Target({ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Component\npublic @interface Service {\n   @AliasFor(\n       annotation = Component.class\n   )\n   String value() default "";\n}\n
Run Code Online (Sandbox Code Playgroud)\n

@Repository注解

\n

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

\n

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

\n
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>\n
Run Code Online (Sandbox Code Playgroud)\n

此 bean 后处理器向任何使用 @Repository 注释的\xe2\x80\x99s bean 添加一个顾问程序。

\n

类似地,@Repository 也是组件注释的子级,用于属于持久数据访问层并充当数据存储库的类。

\n
@Target({ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Component\npublic @interface Repository {\n    @AliasFor(\n        annotation = Component.class\n    )\n    String value() default "";\n}\n
Run Code Online (Sandbox Code Playgroud)\n

概括

\n

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

\n


小智 13

@ Component,@ Service,@ Controller,@ Repository之间没有区别.@Component是表示MVC组件的Generic注释.但是作为我们的MVC应用程序的一部分,将有几个组件,如服务层组件,持久层组件和表示层组件.所以要区分它们Spring人们也给了其他三个注释.

表示持久层组件:@Repository

表示服务层组件:@Service

表示表示层组件:@Controller

或者你可以将@Component用于所有这些.


Amo*_*xit 13

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

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

@Service是专门的注释.它现在没有带来任何新功能,但它澄清了bean的意图

@Controller是专门的注释,它使bean能够识别MVC并允许使用类似的@RequestMapping所有其他注释

这里有更多细节


Bha*_*ath 11

A @Service引用spring文档,

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

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

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

Repository埃里克埃文斯一样,

REPOSITORY将某种类型的所有对象表示为概念集(通常是模拟的).除了具有更精细的查询功能外,它的作用就像一个集合.添加和删​​除相应类型的对象,REPOSITORY后面的机器将它们插入或从数据库中删除它们.该定义收集了一系列有凝聚力的责任,以便从早期生命周期到结束提供对AGGREGATES根源的访问.


Eng*_*ery 11

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

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

现代编程是不同比例的发明、艺术、技术和交流。通信位通常非常重要,因为代码的读取次数通常比编写的次数要多得多。作为程序员,您不仅要尝试解决技术问题,还要尝试将您的意图传达给阅读您代码的未来程序员。这些程序员可能不会分享你的母语,也不会分享你的社交环境,他们有可能在未来 50 年阅读你的代码(这并不像你想象的那么不可能)。很难在遥远的未来进行有效的沟通。因此,使用我们可用的最清晰、最有效、最正确和可交流的语言至关重要。

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

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

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

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


Aru*_*aaj 10

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

@Repository:你注释一个类@Repository,它告诉hibernate它是一个DAO类并将其视为DAO类.意味着它使未经检查的异常(从DAO方法抛出)有资格转换为Spring DataAccessException.

@Service:这告诉hibernate它是一个Service类,你将拥有@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{
Run Code Online (Sandbox Code Playgroud)

你可以通过获得bean对象

CustomerService cust = (CustomerService)context.getBean("AAA");
Run Code Online (Sandbox Code Playgroud)


Myk*_*ura 10

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

@Service,扩展了 @Component 注解,只有命名上的区别。

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

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


Mar*_*ova 9

存储库服务组件注释的子级.所以,所有这些都是组件.存储库服务只是扩展它.究竟怎么样? 服务只有意识形态上的差异:我们将其用于服务.存储库有特殊的异常处理程序.


Jee*_*til 6

刻板印象的解释:

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

@Component是任何Spring托管组件的通用构造型。@Repository@Service@Controller分别是@Component针对特定用例的专业化,例如分别在持久性,服务和表示层。

原来在这里回答。


Pat*_*mil 6

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

@ControllerRestController

@RestController

在此处输入图片说明

  • 此批注是@Controller其自动添加 @Controller@ResponseBody批注的专用版本。因此我们不必添加@ResponseBody映射方法。这意味着 @ResponseBody默认处于活动状态。
  • 如果使用@RestController,则无法返回视图(通过 Viewresolver在Spring / Spring-Boot中使用)
  • @RestController还将响应转换为JSON/XML automaticallyas,@ResponseBody使返回的对象成为体内可能存在的某种东西,e.g. JSON or XML

@Controller

在此处输入图片说明

  • @Controller用于将类标记为Spring MVC Controller。该注释只是其的专用版本,@Component它允许基于类路径扫描自动检测控制器类。
  • @Controller 您可以在Spring Web MVC中返回视图。

更详细的视图


Lov*_*uri 5

Difference between @Component, @Repository, @Controller & @Service annotations

@Component – generic and can be used across application.
@Service – annotate classes at service layer level.
@Controller – annotate classes at presentation layers level, mainly used in Spring MVC.
@Repository – annotate classes at persistence layer, which will act as database repository.

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