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


2103

@Component@Repository@Service注解来春季交替使用,还是他们提供任何特殊的功能,除了作为一个符号设备?

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

还是注释也会影响类的行为和功能?


8
作为具有Microsoft背景的开发人员,我回想起旧的MS SmartClientSoftwareFactory框架(现在已经是不推荐使用的,复杂的分布式桌面应用程序框架)中的服务的语义定义。该定义(由Rich Newman 很好地记录了)将服务定义为无状态可重用对象,最好具有单例作用域,该对象用于对作为参数传递的其他对象执行业务逻辑操作。我倾向于以同样的方式看待春季服务
Ivaylo Slavov 2015年

3
没关系!!无论对您有用的是什么:)我一直讨厌Spring,因为它们总是倾向于为您定义“规则”,这只会给您的应用程序带来微不足道的价值。更不用说Spring附带了自己的庞大堆栈。
TriCore'7

30
@TriCore Sprting是一个框架,为您定义“规则”是它的工作:)
Walfrat

Answers:


1498

Spring文档

@Repository注释是针对满足的存储库(也被称为数据访问对象或DAO)的作用或者固定型的任何类的标记。如Exception Translation中所述,该标记的用途是自动翻译异常

Spring提供进一步典型化注解:@Component@Service,和@Controller@Component是任何Spring托管组件的通用构造型。@Repository@Service@Controller@Component针对更特定用例的专业化(分别在持久性,服务和表示层)。因此,您可以来注解你的组件类有@Component,但是,通过与注解它们@Repository@Service或者@Controller ,你的类能更好地适合于通过工具处理,或与切面进行关联。

例如,这些构造型注释成为切入点的理想目标。@Repository@Service和,并且 @Controller在Spring框架的将来版本中还可以包含其他语义。因此,如果您在使用@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)      
└──────────────┴─────────────────────────────────────────────────────┘

6
将@Controller(或@Component)添加到@WebServlet是否有意义?它不是Spring MVC控制器,但这是概念上最接近的匹配。servlet过滤器呢?
瑞克2014年

1
“持久性层中已经支持@Repository作为自动异常转换的标记”。意思?
2015年

9
这是指这些批注是AOP的良好目标,尽管其他批注尚未定义切入点,但将来可能会这样做。另一方面,@ Repository目前已经是切入点的目标。该切入点用于异常转换,即将技术特定的异常转换为更通用的基于Spring的异常,以避免紧密耦合。
stivlo

3
@stivlo:我真的很努力地理解“刻板印象”一词,但仍然不明白。您能帮我理解这个术语吗?这
很有帮助,

2
@xenoterracide 实际上没有太大区别。带有注释的@Service 内容也是@Component(因为@Service注释本身带有注释@Component)。据我所知,Spring框架中没有任何东西显式地利用事物是a的事实@Service,因此区别实际上只是概念上的。
杰斯珀,

801

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

首先相似

值得再次强调的第一点是,对于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注释,这意味着它们也是@Components。如果我们定义自己的自定义批注并使用批注@Component,则也会使用对其进行扫描<context:component-scan>


@资料库

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

@Repository有什么特别之处?

除了指出这是基于Annotation的Configuration之外,它@Repository的工作是捕获特定于平台的异常,并将它们作为Spring统一的未经检查的异常之一重新抛出。为此,我们提供了PersistenceExceptionTranslationPostProcessor,我们需要像这样在Spring的应用程序上下文中添加:

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

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


@Controller

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

@Controller有什么特别之处?

即使它们看起来相同,我们也无法将其与任何其他类似@Service或切换@Repository。调度程序将扫描@Controller带有@RequestMapping注释的类,并检测其中带有注释的方法。我们可以使用@RequestMapping上/只,其类注释与方法@Controller,这将与工作@Component@Service@Repository等...

注意:如果某个类已经通过任何其他方法(例如,通过@Bean或通过@Component@Service等等...注释)注册为Bean ,则@RequestMapping如果该类也已使用注释进行@RequestMapping注释,则可以选择该类。但这是另一种情况。


@服务

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

@Service有什么特别之处?

除了它用来指示它保持业务逻辑这一事实外,此注释中没有其他值得注意的东西。但是谁知道,Spring将来可能会增加一些额外的例外。


还有什么?

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


如果检测到JPA,将自动注册'PersistenceExceptionTranslationPostProcessor'。
奥尔加(Olga)

21
很棒的解释。您消除了我的很多误会。来自一所大学,我们自下而上地构建了所有项目,即使您自己没有明确地将程序链接在一起,我也很难理解为什么Spring Applications能够正常工作。现在,注释已经很有意义了,谢谢!
NodziGames

那么,@ Service注释对Hibernate(Persistence Layer)意味着什么,除了DI功能外,用于将某种实体提取和映射到相应DTO的Persistence Layer代理又如何呢?该层对于持久性层中的动态性非常重要。如果有人深知它对JPA的影响,那将非常有帮助)))
Musa

1
关于@Controller注解存在一些小错误信息。如果用注释了@RequestMapping类并且以任何方式创建了该类的bean,则不是必需的。任何带有@Controller OR 注释的bean @RequestMapping都将参与Spring MVC的请求映射。例如,这对于以编程方式(例如,使用@Bean方法)创建控制器非常有用,同时可以防止Spring尝试通过程序包扫描来创建控制器(如果不能从扫描中排除程序包)。
Ruslan Stelmachenko

1
这应该是票数最高的答案-回答所有问题并深入探讨。@stivlo对于第一个OP问题-技术差异没有太多解释。
kiedysktos

430

它们几乎相同-所有这些都意味着该类是Spring bean。@Service@Repository并且@Controller是专业@Component的。您可以选择对它们执行特定的操作。例如:

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

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

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

例如最近我做了:

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

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


1
@Component只表示一个Spring bean,还有其他用途吗?
kapil das

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

1
我非常喜欢通用的@Component ...尤其是与@Scope(proxyMode = ScopedProxyMode.//MODE)组合使用
Eddie B

365

@Component等效于

<bean>

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

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

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

  • 控制器只是执行诸如调度,转发,调用服务方法之类的工作。
  • 服务保留业务逻辑,计算等
  • 存储库是DAO(数据访问对象),它们直接访问数据库。

现在您可能会问为什么将它们分开:(我假设您知道面向AOP的面向程序设计)

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

因此,您可以在DAO方法“前后”,“之前”或“之后”记录DAO。之所以可以这样做,是因为您首先拥有了一个DAO。您刚刚实现的是关注点或任务分离。

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

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


6
我有一个基本问题-弹簧机制使用注解,还是仅让程序员记住这些代码是做什么的?
user107986's

25
@ user107986它们主要供程序员记住应用程序中的层。但是@Respository还具有自动异常翻译功能。就像当a中发生异常时一样,@Repository通常会有该异常的处理程序,并且不需要在DAO类中添加try catch块。它与PersistenceExceptionTranslationPostProcessor
Oliver

能否请您编写示例代码,如何为所有“ @Repository”类编写一个联合点。我们要么使用表达式,要么使用bean名称,但是如何说这条建议将适用于所有的“ @Repository”类。
莫妮

同样,尽管注释当前在功能上均相同,但是将来可能会添加给定属性的特定功能。
Cod3Citrus

224

在春天@Component@Service@Controller,和@Repository被典型化注解其用于:

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

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

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

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

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

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

在此处输入图片说明


24
这些答案都很不错,但几乎可以肯定,我们大多数人想要的是服务等组件所提供功能的一些代码示例,我们可以更具体地将其放在脑海中,而不仅仅是诸如“业务逻辑”之类的一般描述。这个对象。否则,我们仍然假设“哦,一切都很好,但我仍然可以对组件应用相同的代码”
dtc

2
并非所有业务逻辑都应纳入服务!就DDD而言,服务应仅包含影响多个实体的域逻辑。请参阅答案stackoverflow.com/a/41358034/238134
deamon

@deamon是的,但取决于开发人员的方法
Harshal Patil 17-4-27的

4
@HarshalPatil当然,您可以编写一个包含服务中所有业务逻辑的应用程序,但这将导致贫乏的领域模型,并且将不必要在实体上强制执行约束和保持一致性。
迪蒙

1
当然,这取决于开发人员的方法。一切都做。如果您错误地解决了问题,即不加任何结构地写任何您想要的内容,并说这是“您的方法”-但这并不正确。当然,“正确”和“错误”被用作描述良好软件开发实践(例如SOLID和其他原理)与不良软件实践(例如“我现在只是想要这样”)之类的术语。
milosmns

71

Spring 2.5引入了更多的构造型注释:@ Component,@ Service和@Controller。@Component用作任何Spring托管组件的通用构造型;而@ Repository,@ Service和@Controller作为@Component的特殊化,用于更具体的用例(例如,分别在持久性,服务和表示层中)。这意味着您可以使用@Component来注释组件类,但是通过使用@ Repository,@ Service或@Controller来注释它们,您的类更适合于通过工具进行处理或与方面相关联。例如,这些构造型注释成为切入点的理想目标。当然,@ Repository,@ Service和@Controller也可能在Spring框架的未来版本中带有其他语义。从而,如果您决定在服务层使用@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文档-类路径扫描,托管组件和使用Java编写配置


48

从技术上讲@Controller@Service@Repository都是一样的。它们都扩展了@Component

从Spring源代码:

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

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

每个注释的目的:

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

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

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


2
替换互换地点是什么意思?controller and repository
Ashish Kamble

46

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

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

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


@Repository可以用于RestAPI调用而不是DB操作吗?
Nayeem

@Nayeem从技术上讲,您可以将服务作为控制器进行注释,将存储库作为服务进行注释,依赖注入的工作原理相同。但是,为什么要这么做呢?如果它不适用于数据库实体-它不是存储库,并且@Repository专门设计用于持久层。如果您使用的是Rest api,则使用的是DTO,而不是DAO。

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.

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
    }
}
  • 每当我们默认添加@Serviceor @Repositroy@Controller注解时,@Component注解就会在类的顶部存在

23

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

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

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

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

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

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


20

我们可以根据java标准来回答

提到JSR-330,Spring现在已支持,您只能使用@Named定义一个bean(Somehow @Named=@Component)。所以,按照这一标准,似乎是没有用定义定型(如@Repository@Service@Controller),以类别豆类。

但是弹簧用户将这些不同的注释以不同的特定用途使用,例如:

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

关于你的第三点。这不是真的。我甚至可以向服务类下的方法添加@RequestMapping注释(我的意思是用@Service注释的类)。
拉胡尔·古普塔

19

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

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

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

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

春天的@Component

“组件专业化”


18

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

  • 表示持久层组件: @Repository
  • 代表服务层组件: @Service
  • 表示表示层组件: @Controller
  • 否则您可以将@Component其全部使用。

17

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

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


15

在春季4,最新版本:

@Repository批注是实现存储库的角色或构造型(也称为数据访问对象或DAO)的任何类的标记。如第20.2.2节“异常转换”中所述,此标记的用途是自动转换异常。

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


15

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

@Repository:您注释一个类@Repository,它告诉休眠是DAO类,并将其视为DAO类。意味着它使未经检查的异常(从DAO方法抛出)可以转换为Spring DataAccessException

@Service:这告诉hibernate这是一个Service类,在其中将具有@Transactionaletc Service层注释,因此hibernate将其视为Service组件。

加号@Service是的预付款@Component。假设Bean类的名称为CustomerService,因为您没有选择XML Bean的配置方式,所以您将Bean注释@Component为Bean。因此,在获取bean对象时,CustomerService cust = (CustomerService)context.getBean("customerService");默认情况下,Spring将小写该组件的第一个字符-从'CustomerService'到'customerService'。您可以使用名称“ customerService”检索此组件。但是,如果@Service对bean类使用批注,则可以通过以下方式提供特定的bean名称:

@Service("AAA")
public class CustomerService{

您可以通过以下方式获取bean对象

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

13

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

@Repository 是专门的注释,它具有转换DAO类中所有未检查的异常的功能

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

@Controller是专业注解这使得豆MVC认识,并允许像使用作进一步的注解中@RequestMapping,所有这些

这里有更多细节


11

@Service到春天引用文档,

指示带注释的类是“服务”,最初由Domain-Driven Design(Evans,2003)定义为“作为接口提供的操作,在模型中是独立的,没有封装状态”。 可能还表明某个类是“业务服务门面”(就核心J2EE模式而言)或类似的东西。此注释是通用的刻板印象,各个团队可以缩小其语义并适当使用。

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

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

Repository埃里克·埃文斯(Eric Evans)一样,

存储库将某种类型的所有对象表示为概念集(通常是模拟的)。除了具有更复杂的查询功能外,它的作用类似于集合。添加和删​​除了适当类型的对象,并且REPOSITORY背后的机器将其插入或从数据库中删除。该定义收集了一系列连贯的职责,以提供从早期生命周期到末期访问AGGREGATES根源的权限。


11

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

@ControllerRestController

@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 Controller。该注释只是其的专用版本,@Component它允许基于类路径扫描自动检测控制器类。
  • @Controller 您可以在Spring Web MVC中返回视图。

更详细的视图


9

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


6

刻板印象的解释:

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

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

原来在这里回答。


5

@ Component,@ Repository,@ Controller和@Service批注之间的区别

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

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


3

在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:component-scan>到xxx-servlet.xml文件中时,spring将在上下文创建/加载阶段自动创建那些使用上述注释进行注释的类的对象。


2

@Component@ Repository@ Service@Controller

@Component是由管理的组件的通用形式春@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管理器(Facade)和事务处理的Facade模式示例


2

这里给出的答案在很大程度上在技术上是正确的,但是即使响应列表很长,而且位于底部,我认为也应该在这里放入一个实际上正确的响应,以防万一有人偶然发现它并从中学到有价值的东西它。并非其他答案都是错误的,只是它们是不正确的。而且,为阻止成群结队,是的,我知道从技术上讲这些注释实际上是同一件事,并且甚至在Spring 5之前都是可以互换的。现在,对于正确的答案:

这三个注释是完全不同的东西,并且不能互换。您可以说出来,因为它们只有三个而不是三个。它们并非旨在互换,只是出于优雅和方便的目的而实施。

现代编程是发明,艺术,技术和交流的不同比例。通信位通常非常重要,因为代码读取的频率通常比其写入的频率高。作为程序员,您不仅要解决技术问题,而且还试图将自己的意图传达给将来阅读代码的程序员。这些程序员可能不会共享您的母语,也不会共享您的社交环境,并且有可能在未来的50年内阅读您的代码(这并不像您想的那样大)。如此遥远的未来很难有效沟通。因此,至关重要的是,我们要使用可用的最清晰,最有效,正确和可交流的语言。

例如,@Repository在编写存储库时使用而不是至关重要@Component。后者对于存储库的注释是非常差的选择,因为它并不表示我们正在查看存储库。我们可以假设存储库也是一个spring-bean,但是不能假定组件是存储库。有了@Repository我们,我们的语言变得清晰而具体。我们清楚地表明这是一个存储库。用@Component我们将它留给读者来决定他们正在阅读哪种类型的组件,他们将不得不阅读整个类(可能还包括子类和接口的树)以推断含义。这样一来,很可能在不久的将来,该类可能会被读者误解为不是存储库,并且我们会对这个错误承担部分责任,因为我们非常清楚这是一个存储库,但未能在我们的语言中明确并有效地传达我们的意图。

我将不去讨论其他示例,但会尽可能清楚地说明:这些注释是完全不同的内容,应根据其意图适当使用。@Repository用于存储库,没有其他注释正确。@Service用于服务,没有其他注释正确。@Component用于既不是目录又不是服务的组件,并且在原位置使用这两个组件也不正确。它可能会编译,甚至可以运行并通过您的测试,但这是错误的,如果您这样做,我会(在专业上)会少考虑您。

整个春季都有这样的例子(以及一般的编程)。@Controller编写REST API时,请勿使用,因为@RestController它可用。您不能使用@RequestMappingwhen @GetMapping是有效的替代方法。Etc. Etc. Etc.您必须选择最具体的准确和正确的语言,才能将您的意图传达给您的读者,否则,您会将风险引入系统中,而风险是有代价的。


说的好点!
安迪

1

为了简化此说明,让我们按用例考虑技术性,这些注解用于注入,正如我所说的“ 用于注入 ”,也就是说,如果您知道如何使用依赖注入“ DI”, 并且应该,那么您将始终寻找这些注释,并通过使用这些Stereo Types注释这些类,来通知DI容器对其进行扫描以准备在其他地方进行注入,这是实际的目标。

现在让我们移动到每个;首先@Service,如果您要为特定业务案例构建一些逻辑,则需要在包含业务逻辑的地方将其分开,此服务是普通Class,或者您可以将其用作接口,并且其编写方式类似于这个

@Service
public class Doer {
   // Your logic 
}

// To use it in another class, suppose in Controller 
@Controller
public class XController {
 // You have to inject it like this 
 @Autowired 
 private Doer doer;
}

注入它们时,所有方法都是相同的,@ Repository是一个接口,适用于Repository Pattern Repository设计模式的实现,通常在处理某些数据存储或数据库时使用,您会发现它包含多个为您处理数据库操作的现成实现;它可以是 CrudRepositoryJpaRepository等。

// For example
public interface DoerRepository implements JpaRepository<Long, XEntity> {}

最后@Component,这是Spring中已注册bean的通用形式,即Spring一直在寻找标记有@Component的bean进行注册,然后@Service和@Repository都是@Component的特例,但是是常见的用例组件是指您制作纯粹是技术性的东西而不是涵盖直接业务案例的时候!例如格式化日期或处理特殊请求序列化机制等。


0

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

@服务扩展了@Component批注,仅具有命名差异。

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

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


-13
@Component
@Controller
@Repository
@Service
@RestController

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.