关于Java:Spring中的@Component, @Repository & @Service annotations有什么不同?

What's the difference between @Component, @Repository & @Service annotations in Spring?

CAN @Component@Repository@Serviceannotations interchangeably在弹簧或可用于任何特定的功能,此外,他们提供的标记装置的作用?

在其他的话,如果我有一个服务类的变化从第一到@Component@Service注释,将它的行为以同样的方式吗?

或做注释的行为也影响和功能的类?


从Spring文档:

In Spring 2.0 and later, the @Repository annotation is a marker for
any class that fulfills the role or stereotype (also known as Data
Access Object or DAO) of a repository. Among the uses of this marker
is the automatic translation of exceptions.

Spring 2.5 introduces further stereotype annotations: @Component,
@Service, and @Controller. @Component is a generic stereotype for any
Spring-managed component. @Repository, @Service, and @Controller are
specializations of @Component for more specific use cases, for
example, in the persistence, service, and presentation layers,
respectively.

Therefore, you can annotate your component classes with @Component,
but by annotating them with @Repository, @Service, or @Controller
instead, your classes are more properly suited for processing by tools
or associating with aspects. For example, these stereotype annotations
make ideal targets for pointcuts.

Thus, if you are choosing between using @Component or @Service for
your service layer, @Service is clearly the better choice. Similarly,
as stated above, @Repository is already supported as a marker for
automatic exception translation in your persistence layer.

1
2
3
4
5
6
7
8
┌────────────┬─────────────────────────────────────────────────────┐
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)      │
└────────────┴─────────────────────────────────────────────────────┘


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

First the Similarity

First point worth highlighting again is that with respect to scan-auto-detection and dependency injection for BeanDefinition all these annotations (viz., @Component, @Service,
@Repository, @Controller) are the same. We can use one in place
of another and can still get our way around.

@component、@repository、@controller和@service之间的差异

@Component

这是一个通用的原型注释,指示类是一个Spring组件。

@component有什么特别之处只扫描@Component,一般不查找@Controller@Service@Repository。扫描它们是因为它们本身带有@Component的注释。

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

1
2
3
4
@Component
public @interface Service {
    ….
}

nbsp;

1
2
3
4
@Component
public @interface Repository {
    ….
}

nbsp;

1
2
3
4
@Component
public @interface Controller {
    …
}

因此,可以说@Controller@Service@Repository@Component注释的特殊类型。接收它们并将它们的后续类注册为bean,就像它们被@Component注释一样。

特殊类型注释也会被扫描,因为它们本身是用@Component注释注释的,也就是说它们也是@Component注释。如果我们定义自己的自定义注释并用@Component注释,它也会被扫描。

@Repository

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

@repository有什么特别之处?

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

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

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

@Controller

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

@controller有什么特别之处?

我们不能将此注释与任何其他类似于@Service@Repository的注释进行切换,即使它们看起来相同。调度器扫描用@Controller注释的类,并检测其中的@RequestMapping注释。我们只能在用@Controller注释的类中使用@RequestMapping

@Service

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

@service有什么特别之处?

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

What else?

与上述类似,在未来的春天,可以根据分层约定为@Service@Controller@Repository添加特殊功能。因此,尊重惯例并按照层次使用它总是一个好主意。


它们几乎是相同的-所有这些都意味着这个班是一个菜豆。@Service@Repository@Controller是专门的@Components。您可以选择对它们执行特定的操作。例如:

  • 弹簧MVC使用@Controller
  • @Repositorybean可以进行持久性异常转换。

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

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

例如,最近我做了:

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

因此,所有用@ScheduledJob注释的类都是SpringBean,除了这些类之外,它们还注册为Quartz作业。您只需要提供处理特定注释的代码。


@分量等于

1
<bean>

@服务,@controller,@repository=@component+一些更特殊的功能

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

这三个注释用于分隔应用程序中的"层"。

  • 控制器只是做一些诸如调度、转发、呼叫服务方法等的事情。
  • 服务保留业务逻辑、计算等。
  • 存储库是DAOS(数据访问对象),它们直接访问数据库。

现在您可能会问为什么要将它们分开:(我假设您了解面向方面的AOP编程)

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

因此,您可以对DAO方法执行"around"、"before"或"after"的日志记录。你可以这样做,因为你首先有一把刀。你刚刚实现的是关注点或任务的分离。

想象一下,如果只有一个annotation@controller,那么这个组件的调度、业务逻辑和访问数据库都是混合的,所以代码太脏了!

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


在春季,@Component@Service@Controller@Repository是原型注释,用于:

@Controller:在完成了从表示页的请求映射的情况下,即表示层不会转到任何其他文件,它直接转到@Controller类,并检查@RequestMapping注释中的请求路径,必要时在方法调用之前写入该注释。

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

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

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

Indicates that an annotated class is a"component". Such classes are
considered as candidates for auto-detection when using
annotation-based configuration and classpath scanning.

Other class-level annotations may be considered as identifying a
component as well, typically a special kind of component: e.g. the
@Repository annotation or AspectJ's @Aspect annotation.

enter image description here


Spring 2.5 introduces further stereotype annotations: @Component, @Service and @Controller. @Component serves as a generic stereotype for any Spring-managed component; whereas, @Repository, @Service, and @Controller serve as specializations of @Component for more specific use cases (e.g., in the persistence, service, and presentation layers, respectively). What this means is that you can annotate your component classes with @Component, but by annotating them with @Repository, @Service, or @Controller instead, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets for pointcuts. Of course, it is also possible that @Repository, @Service, and @Controller may carry additional semantics in future releases of the Spring Framework. Thus, if you are making a decision between using @Component or @Service for your service layer, @Service is clearly the better choice. Similarly, as stated above, @Repository is already supported as a marker for automatic exception translation in your persistence layer.

1
2
3
4
@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编写配置


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

  • 对所有Web服务类型的DB连接使用@Service
  • 对所有存储过程数据库连接使用@Repository
  • 如果不使用正确的注释,则可能会面临由回滚事务重写的提交异常。您将在压力负载测试期间看到与回滚JDBC事务相关的异常。


    @存储库@service和@controller用作@component的专门化,以便更具体地使用。在此基础上,您可以将@service替换为@component,但在这种情况下,您将失去专门化。

    1
    2
    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.

    技术上,@controller,@service,@repository都是相同的。它们都扩展了@components。

    从Spring源代码:

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

    我们可以直接为每个bean使用@component,但是为了更好地理解和维护大型应用程序,我们使用@controller、@service、@repository。

    每个注释的目的:

    1)@controller->classes用此注释,用于接收客户端的请求。第一个请求到达Dispatcher servlet,在那里它使用@requestmapping annotation的值将请求传递给特定的控制器。

    2)@service->classes用这个注释,目的是操作我们从客户机接收或从数据库获取的数据。所有使用数据的操作都应该在这个层中完成。

    3)@repository->classes加上注释后,用于连接数据库。它也可以被视为DAO(数据访问对象)层。此层应仅限于CRUD(创建、检索、更新、删除)操作。如果需要任何操作,则应将数据发送回@service layer。

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

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


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

    • If we add the @Component then it tells the role of class is a component class it means it is a class consisting some logic,but it
      does not tell whether a class containing a specifically business or
      persistence or controller logic so we don't use directly this
      @Component annotation
    • If we add @Service annotation then it tells that a role of class consisting business logic
    • If we add @Repository on top of class then it tells that a class consisting persistence logic
    • Here @Component is a base annotation for @Service,@Repository and @Controller annotations

    例如

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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注释将在类的顶部存在。

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

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

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

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

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

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


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

    1
    2
    3
    4
    5
    @Component
    public class AdressComp{
        .......
        ...//some code here    
    }

    @组件是任何Spring管理的组件的通用原型。

    @控制器、@service和@repository是@component针对特定用例的专门化。

    @弹簧组件

    Component Specialization


    我们可以按照Java标准来回答这个问题。

    参照现在由Spring支持的JSR-330,您只能使用@Named来定义bean(不知何故@Named=@Component)。因此,根据这个标准,似乎没有必要对bean类定义刻板印象(如@Repository@Service@Controller)。

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

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

  • 春季4日,最新版本:

    The @Repository annotation is a marker for any class that fulfills the
    role or stereotype of a repository (also known as Data Access Object
    or DAO). Among the uses of this marker is the automatic translation of
    exceptions as described in Section 20.2.2,"Exception translation".

    Spring provides further stereotype annotations: @Component, @Service,
    and @Controller. @Component is a generic stereotype for any
    Spring-managed component. @Repository, @Service, and @Controller are
    specializations of @Component for more specific use cases, for
    example, in the persistence, service, and presentation layers,
    respectively. Therefore, you can annotate your component classes with
    @Component, but by annotating them with @Repository, @Service, or
    @Controller instead, your classes are more properly suited for
    processing by tools or associating with aspects. For example, these
    stereotype annotations make ideal targets for pointcuts. It is also
    possible that @Repository, @Service, and @Controller may carry
    additional semantics in future releases of the Spring Framework. Thus,
    if you are choosing between using @Component or @Service for your
    service layer, @Service is clearly the better choice. Similarly, as
    stated above, @Repository is already supported as a marker for
    automatic exception translation in your persistence layer.


    即使我们交换@component、@repository或@service

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


    @component、@service、@controller、@repository之间没有区别。@组件是表示MVC组件的通用注释。但作为我们MVC应用程序的一部分,将有几个组件,如服务层组件、持久层组件和表示层组件。所以为了区分它们,春天的人们也给出了另外三个注解。

    表示持久层组件:@repository

    表示服务层组件:@service

    表示表示表示层组件:@controller

    或者,您可以对所有组件使用@component。


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

    @Repository是一种特殊的注释,它具有转换DAO类中所有未检查的异常的特性。

    @Service是专门的注释。到目前为止,它没有带来任何新的特性,但它澄清了bean的意图。

    @控制器是专门的注释,它使bean mvc意识到并允许使用进一步的注释,如@RequestMapping,以及所有这样的注释。

    以下是详细信息


    一份@Service引用Spring文档,

    Indicates that an annotated class is a"Service", originally defined
    by Domain-Driven Design (Evans, 2003) as"an operation offered as an
    interface that stands alone in the model, with no encapsulated state."
    May also indicate that a class is a"Business Service Facade" (in the
    Core J2EE patterns sense), or something similar. This annotation is a
    general-purpose stereotype and individual teams may narrow their
    semantics and use as appropriate.

    如果你看看埃里克·埃文斯的领域驱动设计,

    A SERVICE is an operation offered as an interface that stands alone in
    the model, without encapsulating state, as ENTITIES and VALUE OBJECTS
    do. SERVICES are a common pattern in technical frameworks, but they
    can also apply in the domain layer. The name service emphasizes the
    relationship with other objects. Unlike ENTITIES and VALUE OBJECTS, it
    is defined purely in terms of what it can do for a client. A SERVICE
    tends to be named for an activity, rather than an entity—a verb rather
    than a noun. A SERVICE can still have an abstract, intentional
    definition; it just has a different flavor than the definition of an
    object. A SERVICE should still have a defined responsibility, and that
    responsibility and the interface fulfilling it should be defined as
    part of the domain model. Operation names should come from the
    UBIQUITOUS LANGUAGE or be introduced into it. Parameters and results
    should be domain objects. SERVICES should be used judiciously and not
    allowed to strip the ENTITIES and VALUE OBJECTS of all their behavior.
    But when an operation is actually an important domain concept, a
    SERVICE forms a natural part of a MODEL-DRIVEN DESIGN. Declared in the
    model as a SERVICE, rather than as a phony object that doesn't
    actually represent anything, the standalone operation will not mislead
    anyone.

    根据埃里克·埃文斯的说法,还有一个Repository

    A REPOSITORY represents all objects of a certain type as a conceptual
    set (usually emulated). It acts like a collection, except with more
    elaborate querying capability. Objects of the appropriate type are
    added and removed, and the machinery behind the REPOSITORY inserts
    them or deletes them from the database. This definition gathers a
    cohesive set of responsibilities for providing access to the roots of
    AGGREGATES from early life cycle through the end.


    @组件:注释一个class@component,它告诉Hibernate它是一个bean。

    @存储库:您注释一个类@repository,它告诉Hibernate它是一个DAO类,并将其视为DAO类。意味着它使未检查的异常(从DAO方法抛出)有资格转换为SpringDataAccessException。

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

    加上@service是@component的高级。假设bean类名为customerservice,因为您没有选择XML bean配置方式,所以用@component注释bean以将其指示为bean。因此,在默认情况下获取bean对象CustomerService cust = (CustomerService)context.getBean("customerService");的同时,spring会将组件的第一个字符从"customerservice"降低为"customerservice"。您可以检索名为"customerservice"的组件。但是,如果对bean类使用@service注释,则可以通过以下方式提供特定的bean名称:

    1
    2
    @Service("AAA")
    public class CustomerService{

    你可以通过

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


    存储库和服务是组件注释的子项。所以,它们都是组成部分。存储库和服务只是扩展它。究竟如何?服务只有意识形态上的区别:我们用它来服务。存储库具有特定的异常处理程序。


    刻板印象的解释:

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

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

    最初在这里回答。


    @组件,@repository,@service,@controller:

    @组件是由spring@repository、@service和@controller管理的组件的通用构造型,它们是@component专门用于更具体的用途:

    • @持久性存储库
    • @服务和交易服务
    • @MVC控制器控制器

    为什么要在@component上使用@repository、@service、@controller?我们可以用@component标记我们的组件类,但是如果我们使用的是适应预期功能的替代方法。我们的类更适合于每种特定情况下预期的功能。

    用"@repository"注释的类具有更好的翻译和可读的错误处理能力,可以使用org.springframework.dao.dataaccessexception。非常适合实现访问数据的组件(DataAccessObject或DAO)。

    带有"@controller"的注释类在SpringWebMVC应用程序中扮演控制器角色。

    带有"@service"的注释类在业务逻辑服务中扮演着角色,例如DAO管理器(facade)的facade模式和事务处理。


    在Spring框架中,提供了一些特殊类型的注释,称为构造型注释。如下所示:

    1
    2
    3
    4
    5
    @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文件中时,spring将在上下文创建/加载阶段自动创建用上面注释的那些类的对象。


    1
    2
    3
    4
    5
    @component
    @controller
    @Repository
    @service
    @RestController

    这些都是刻板的注释。这对于将类作为IOC容器中的SpringBeans来制作很有用,