首页 文章

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

提问于
浏览
1668

@Component@Repository@Service 注释可以在Spring中互换使用,还是除了作为符号设备之外还提供任何特定功能?

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

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

24 回答

  • 1
    @component
    @controller
    @Repository
    @service
    @RestController
    

    这些都是StereoType注释 . 如果我们把@controller放在课堂上 . 它不会成为基于我们可以用这个注释注释的不同层(组件)的控制器类,但编译器不会对此做任何事情只是为了开发人员的理解目的我们可以根据我们必须编写的注释组件进行选择

  • 13

    来自Spring Documentation

    在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)      │
    └────────────┴─────────────────────────────────────────────────────┘
    
  • 3

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

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

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

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

    @Component in Spring

  • 24

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

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

    spring-mvc使用

    • @Controller beans

    • @Repository beans有资格进行持久性异常转换

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

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

    例如最近我做了:

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

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

  • 403

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

    • 对所有Web服务类型的数据库连接使用 @Service

    • 对所有存储的proc DB连接使用 @Repository

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

  • 201

    @Service 引用spring文档,

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

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

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

    和Eric Evans一样 Repository

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

  • 8

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

    表示持久层组件:@Repository

    表示服务层组件:@Service

    表示表示层组件:@Controller

    否则你可以将@Component用于所有这些 .

  • 21

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

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

  • 18

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

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

  • 16

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

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

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

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

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

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

  • 64

    Explanation of stereotypes :

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

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

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

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

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

    原来回答here .

  • -2

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

    并且您可以通过获取bean对象

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

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

    @Controller: 其中 request mapping from presentation page 完成,即表示层将不会转到任何其他文件,它直接转到 @Controller 类,并检查 @RequestMapping 注释中的请求路径,如果需要,在方法调用之前写入 .

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

    @Repository :这是应用程序的持久层(数据访问层),用于从数据库中获取数据 . 即 all the Database related operations are done by the repository.

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

    表示带注释的类是“组件” . 当使用基于注释的配置和类路径扫描时,这些类被视为自动检测的候选者 . 其他类级注释也可以被认为是识别组件,通常是特殊类型的组件:例如, @Repository注释或AspectJ的@Aspect注释 .

  • 23

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

    引用现在由spring支持的 JSR-330 ,您只能使用 @Named 来定义bean(以某种方式 @Named=@Component ) . 所以根据这个标准,似乎没有用于定义类别bean的构造型(如 @Repository@Service@Controller ) .

    但是 spring 用户将这些不同的注释用于特定用途,例如:

    • 帮助开发人员为主管人员定义更好的类别 . 在某些情况下,这种分类可能会有所帮助 . (例如,当您使用 aspect-oriented 时,这些可能是 pointcuts 的良好候选者)

    • @Repository 注释将为您的bean添加一些功能(一些自动异常转换到您的bean持久层) .

    • 如果您使用的是Spring MVC,则 @RequestMapping 只能添加到由 @Controller 注释的类中 .

  • 9

    @Component相当于

    <bean>
    

    @Service, @Controller, @Repository = {@Component + some more special functionality}

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

    这三个注释用于在您的应用程序中分隔 "Layers"

    • 控制器只是执行调度,转发,调用服务方法等操作 .

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

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

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

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

    因此,您可以记录DAO "around","before"或"after" DAO方法 . 你可以这样做,因为你首先有一个DAO . 你刚才取得的成就是 Separation of concerns or tasks.

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

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

  • 11

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

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

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

    @Controller是专门的注释,它使bean知道MVC并允许使用像 @RequestMapping 这样的进一步注释

    这里有更多details

  • 343

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

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


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

    @Component

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

    What’s special about @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 注释它,那么它也将被 <context:component-scan> 扫描


    @Repository

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

    What’s special about @Repository?

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

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

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


    @Controller

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

    What’s special about @Controller?

    我们无法将此注释与 @Service@Repository 等任何其他注释切换,即使它们看起来相同 . 调度程序扫描使用 @Controller 注释的类,并检测其中的 @RequestMapping 注释 . 我们只能在 @Controller 注释类上使用 @RequestMapping .


    @Service

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

    What’s special about @Service?

    除了它用于表明它持有业务逻辑这一事实之外,这个注释没有明显的特点,但是谁知道,spring可能在未来增加一些额外的特殊功能 .


    还有什么?

    与上面类似,将来Spring可能会根据它们的分层约定选择为 @Service@Controller@Repository 添加特殊功能 . 因此,尊重惯例并将其与层一致使用始终是一个好主意 .

  • 3

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

    如果我们添加@Component然后它告诉类的角色是一个组件类,它意味着它是一个包含一些逻辑的类,但它不会告诉一个类是否包含特定的业务或持久性或控制器逻辑,所以我们不直接使用这个@Component注释如果我们添加@Service注释,那么它会告诉包含业务逻辑的类的角色如果我们在类之上添加@Repository,那么它会告诉包含持久性逻辑的类这里@Component是@的基本注释服务,@ 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 注释将存在于该类的顶部
  • 16

    在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将自动创建那些在上下文创建/加载阶段用上面的注释注释的类的对象 .

  • 1237

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

    来自Spring的源代码:

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

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

    每个注释的目的:

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

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

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

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

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

  • 1

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

  • 41

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

  • 8

    @Component,@ Repository,@ Service,@ Controller:

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

    • @Repository用于持久化

    • @服务和交易服务

    • @ Controller用于MVC控制器

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

    使用“@Repository”注释的类使用org.springframework.dao.DataAccessException具有更好的转换和可读错误处理 . 非常适合实现访问数据的组件(DataAccessObject或DAO) .

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

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

相关问题