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

@Repository @Component@Repository@Service注释可以在Spring中互换使用,还是除了充当符号设备之外还可以提供任何特定的function吗?

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

或者注释是否也会影响课堂的行为和function?

从Spring文档 :

在Spring 2.0和更高版本中,@Repository注释是任何实现存储库angular色或构造型(也称为数据访问对象或DAO)的类的标记。 这个标记的用途是自动翻译exception。

Spring 2.5引入了更多的构造型注释:@Component,@Service和@Controller。 @Component是任何Springpipe理组件的通用构造型。 对于更具体的用例,@Repository,@Service和@Controller是@Component的特化,例如,分别在持久层,服务层和表示层。

因此,你可以使用@Component注释你的组件类,而是用@Repository,@Service或者@Controller来注释它们,这样你的类就更适合用工具处理或者与方面相关联。 例如,这些刻板印象注解为切入点提供了理想的目标。

因此,如果您在为您的服务层使用@Component或@Service之间进行select,@Service显然是更好的select。 同样,如上所述,已经支持@Repository作为持久层自动exception转换的标记。

 | 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) | 

它们几乎是一样的 – 它们都意味着这个类是一个Spring bean。 @Service @Controller@Repository@Controller是专门的@Component 。 您可以select执行特定的操作。 例如:

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

另一件事是你指定组件在语义上不同的层次。

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

例如最近我做了:

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

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

@Component相当于

 <bean> 

@Service,@Controller,@Repository = {@Component +更多特殊function}

这意味着Service,Controller和Repository在function上是相同的。

这三个注释是用来分隔你的应用程序中的“层”

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

现在你可能会问为什么把它们分开:(我假设你知道面向方面编程的AOP方面)

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

因此,您可以在DAO方法的“周围”,“之前”或“之后”执行DAO的日志logging。 你可以这样做,因为你有一个DAO。 你刚刚取得的成就是关注点或任务的分离。

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

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

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

首先是相似性

首先值得再次强调的是, 就BeanDefinition的扫描自动检测和dependency injection而言,所有这些注解(即@Component,@Service,@ Repository,@Controller)都是相同的。 我们可以用一个替代另一个,仍然可以绕过。


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

@零件

这是一个通用的刻板印象注释,表明该类是一个弹簧组件。

@Component有什么特别之处?
<context:component-scan>只扫描@Component并且通常不寻找@Controller@Service @Controller@Repository 。 他们被扫描,因为他们自己用@Component注释。

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

 @Component public @interface Service { …. } 
 @Component public @interface Repository { …. } 
 @Component public @interface Controller { … } 

因此, @Controller@Service @Controller@Repository@Component注解的特殊types是没有错的。 <context:component-scan>选取它们并将它们的下面的类注册为bean,就好像它们用@Component注解一样。

他们被扫描,因为他们自己用@Component注释注释。 如果我们定义自己的自定义注释并用@Component注释它,那么它也将被扫描<context:component-scan>


@Repository

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

@Repository有什么特别之处?

除了指出这是一个基于注解的configuration之外@Repository的工作是捕获特定于平台的exception,并将它们作为Spring统一的非检查exception之一重新抛出。 为此,我们提供了PersistenceExceptionTranslationPostProcessor ,我们需要在Spring的应用程序上下文中添加如下代码:

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

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


@Controller

@Controller注释表示一个特定的类服务于控制器的angular色。 @Controller批注充当注释类的刻板印象,表明其作用。

@Controller有什么特别之处?

我们不能像@Service@Repository那样使用其他任何types的注释,即使它们看起来相同。 调度程序扫描用@Controller注释的类并检测其中的@RequestMapping注释。 我们只能在@Controller注释类上使用@RequestMapping


@服务

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

@Service有什么特别之处?

除了用来表示它拥有业务逻辑的事实外,这个注释并没有明显的特点,但是谁知道,spring可能会在未来增加一些额外的特性。


还有什么?

与上面类似,未来的Spring可以根据层次约定为@Service @Controller@Repository @Controller@Repository添加特殊的function。 因此,尊重这个惯例总是一个很好的主意,并且按照层次使用它们。

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

@Controller:你的请求 映射从演示文稿页面完成,即表示层不会去任何其他文件它直接到@Controller类,并检查所需的path在@RequestMapping注释写在方法调用之前,如果有必要。

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

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

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

指示注释类是“ 组件 ”。 当使用基于注释的configuration和类path扫描时,这些类被认为是自动检测的候选对象。

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

在这里输入图像描述

Spring 2.5引入了更多的构造型注释:@Component,@Service和@Controller。 @Component是任何Springpipe理组件的通用构造型; 而@Repository,@Service和@Controller则作为@Component的特化用于更具体的用例(例如分别在持久层,服务层和表示层)。 这意味着你可以用@Component注释你的组件类,而是用@Repository,@Service或者@Controller来注释它们,这样你的类就更适合用工具处理或者与方面相关联。 例如,这些刻板印象注解为切入点提供了理想的目标。 当然,@Repository,@Service和@Controller也可能在Spring Framework的未来版本中增加额外的语义。 因此,如果你正在为你的服务层使用@Component或@Service做出决定,@Service显然是更好的select。 同样,如上所述,已经支持@Repository作为持久层自动exception转换的标记。

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

参考: – http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s12.html

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

你会注意到所有@Repository@Service @Controller或者@Controller都是用@Component注解的。 那么,我们可以只使用@Component来进行自动扫描的所有组件吗? 是的,你可以,Spring会自动扫描所有组件的@Component注释。

它工作正常,但不是一个好的做法,为了可读性,您应该总是为指定图层声明@Repository@Service @Controller@Controller ,以使您的代码更易于阅读。

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

  1. 对所有Web服务types的数据库连接使用@Service
  2. 对所有存储的proc数据库连接使用@Repository

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

@Component,@Service和@Repository之间的区别

这些刻板印象之间的主要区别在于它们被用于不同的分类。

在一个多层应用程序中,我们将会有不同的层次,比如演示,服务,业务,数据访问等等。当一个类被Spring注释为自动检测时,我们应该使用各自的原型。

@Component – generics,可以跨应用程序使用。
@Service – 在服务层级别注释类。
@Repository – 在持久层注释类,它将充当数据库存储库。

如果技术上他们会一样,那么为什么我们需要在不同层次上使用这些。 为什么不在所有图层中使用相同的图层? 例如,如果我们在所有图层中使用@Service ,所有的bean都将被实例化,并且没有问题。 有一个小小的差异,例如考虑@Repository

后处理程序自动查找所有exception转换程序(PersistenceExceptionTranslator接口的实现),并build议所有标记有@Repository注释的bean,以便发现的转换程序可以拦截并在抛出的exception上应用适当的转换。

和上面类似,未来Spring可以根据层次约定为@Service @Controller@Repository @Controller@Repository添加值。 为了这个附加的function优势,它更好地尊重约定,并使用它们与层次。

除上述以外,就扫描自动检测而言,BeanDefinition @Component @Service@Repository @Controller@Repository@Controller Controller的dependency injection是相同的。

@Repository @Service@Controller是作为@Component的特化,在这个基础上更具体的使用,你可以把@Servicereplace成@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. 

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

  • 如果我们添加@Component,那么它告诉类的angular色是一个组件类,它意味着它是一个包含一些逻辑的类,但它不能告诉一个类是否包含特定的业务或持久性或控制器逻辑,所以我们不使用直接这个@Component注解
  • 如果我们添加@Service注释,那么它就会告诉我们一个由业务逻辑构成的类的angular色
  • 如果我们在类的顶部添加@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注释将在类的顶部存在

在一个多层应用程序中,我们将会有不同的层次,比如演示,服务,业务,数据访问等等。当一个类被Spring注释为自动检测时,我们应该使用各自的原型。

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

这些刻板印象之间的主要区别是它们被用于不同的分类。

2.在多层应用程序中,我们将有不同的层次,如演示文稿,服务,业务,数据访问等。当一个类将被Spring注释为自动检测时,我们应该使用各自的刻板印象如下。

  • @Component – generics,可以跨应用程序使用。
  • @Service – 在服务层级别注释类。
  • @Controller – 在表示层级注释类,主要用于Spring MVC。
  • @Repository – 在持久层注释类,它将充当数据库存储库。 如果技术上他们会一样,那么为什么我们需要在不同层次上使用这些。 为什么不在所有图层中使用相同的图层? 例如,如果我们在所有图层中使用@Service,所有的bean都将被实例化,并且没有问题。 有一个小小的差异,例如考虑@Repository。

后处理程序自动查找所有exception转换程序(PersistenceExceptionTranslator接口的实现),并build议所有标记有@Repository注释的bean,以便发现的转换程序可以拦截并在抛出的exception上应用适当的转换。

  1. 和上面类似,未来Spring可以根据层次约定为@Service @Controller@Repository @Controller@Repository添加值。 为了增加function优势,最好遵守约定,并按照层次使用它们。
  2. 除上述以外,就扫描自动检测而言 ,BeanDefinition @Component @Service@Repository @Controller@Repository@Controller Controller的dependency injection是相同的。
  3. 按照Spring文档: @Repository注释是任何实现存储库 (也称为数据访问对象或DAO )angular色或构造型的类的标记。 这个标记的用法是自动翻译exception,如第20.2.2节“exception转换”中所述。 Spring提供了更多的构造型注释: @Component,@ Service@Controller@Component任何Springpipe理组件通用 构造 @Repository,@Service和@Controller@Component专用,用于更具体的用例 ,例如分别在持久性,服务和表示层。 因此,你可以使用@Component注释你的组件类,而是用@Repository,@Service或者@Controller来注释它们,这样你的类就更适合用工具处理或者与方面相关联。 例如,这些刻板印象注解为切入点提供了理想的目标。 @Repository,@Service和@Controller也可能在Spring Framework的未来版本中携带额外的语义。 因此,如果您在为您的服务层使用@Component或@Service之间进行select,@Service显然是更好的select。 同样,如上所述,已经支持@Repository作为持久层自动exception转换的标记。

在Spring框架中,Spring @Component,@Service,@ Repository和@Controller注释用于使用类path扫描进行自动Bean检测。

@Component是一个通用的注释。 @Service,@Repository,@Controller与@Component的不同之处在于它们是@Component的特例,用于特殊目的。 区别仅仅是分类。

对于所有这些注释(刻板印象),技术上核心目的是相同的。 Spring自动扫描并标识所有这些用“@Component,@Service,@Repository,@Controller”注解的类,并用ApplicationContext注册Bean Definition。

Spring提供了四种不同types的自动组件扫描注释,它们是@Component Component, @Repository @Controller@Repository@Controller 。 从技术上来说,它们之间没有任何区别,但是每个汽车组件扫描注释都应该用于特殊目的,并在定义的层中使用。

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

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

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

@Repository :你需要在持久层中使用这个注解,这就像数据库存储一样。

我们应该select@Component更特殊的forms,同时注释他们的类,因为这个注释可能包含特定的行为。

在春季4,最新版本:

@Repository注释是任何实现存储库(也称为数据访问对象或DAO)angular色或构造型的类的标记。 这个标记的用法是自动翻译exception,如第20.2.2节“exception转换”中所述。

Spring提供了更多的构造型注释:@Component,@Service和@Controller。 @Component是任何Springpipe理组件的通用构造型。 对于更具体的用例,@Repository,@Service和@Controller是@Component的特化,例如,分别在持久层,服务层和表示层。 因此,你可以使用@Component注释你的组件类,而是用@Repository,@Service或者@Controller来注释它们,这样你的类就更适合用工具处理或者与方面相关联。 例如,这些刻板印象注解为切入点提供了理想的目标。 @Repository,@Service和@Controller也可能在Spring Framework的未来版本中携带额外的语义。 因此,如果您在为您的服务层使用@Component或@Service之间进行select,@Service显然是更好的select。 同样,如上所述,已经支持@Repository作为持久层自动exception转换的标记。

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

它的行为是一样的,但是一个方面是,如果我们使用component或@ service,他们将无法捕获与DAO相关的特定exception,而不是Repository

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

参考Spring现在支持的JSR-330 ,你只能使用@Named来定义一个bean(有些怎么@Named=@Component )。 所以根据这个标准,似乎没有必要定义立体声types(比如@Repository@Service @Repository@Service @Controller )来分类bean。

但spring定义这些刻板印象

  1. 帮助开发人员为主pipe人员定义更好的类别。 这种分类在某些情况下可能会有所帮助。 (例如,当您使用aspect oriented ,这些可能是point cuts好select)
  2. 目前只有@Repository注解会为你的bean添加一些function(一些自动exception转换到你的bean持久层)。
  3. 如果你使用spring mvc,@ @RequestMapping只能被添加到@Controller注解的类中。

@ Component,@ Service,@ Controller,@ Repository之间没有区别。 @Component是通用注释来表示我们的MVC组件。 但是,将会有几个组件作为MVC应用程序的一部分,如服务层组件,持久层组件和表示层组件。 所以为了区分他们spring的人也给了另外三个注释。

表示持久层组件:@Repository

表示服务层组件:@Service

表示表示层组件:@Controller

否则你可以使用@Component来处理它们。

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

源自Spring源码:

指示注释类是“组件”。 当使用基于注释的configuration和类path扫描时,这些类被认为是自动检测的候选对象。

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

每个注释的目的:

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

2)@Service – >用这个注解的类,是为了操纵我们从客户端接收到的数据或从数据库中获取的数据。 所有的数据操作都应该在这一层完成。

3)@Repository – >用这个注解的类,打算连接数据库。 它也可以被认为是DAO(数据访问对象)层。 这一层应该仅限于CRUD(创build,检索,更新,删除)操作。 如果需要进行任何操作,则应将数据发送回@Service层。

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

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

一个引用spring文档的@Service

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.

If you look at domain driven design by eric evans,

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.

and a Repository as per Eric Evans,

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.

@Component is the top level generic annotation which makes the annotated bean to be scanned and available in the DI container

@Repository is specialized annotation and it brings the feature of converting all the unchecked exceptions from the DAO classes

@Service is specialized annotation. it do not bring any new feature as of now but it clarifies the intent of the bean

@Controller is specialized annotation which makes the bean MVC aware and allows the use of further annotation like @RequestMapping and all such

Here are more details

@Component : you annotate a class @Component, it tells hibernate that it is a Bean.

@Repository : you annotate a class @Repository, it tells hibernate it is a DAO class and treat it as DAO class. Means it makes the unchecked exceptions (thrown from DAO methods) eligible for translation into Spring DataAccessException.

@Service : This tells hibernate it is a Service class where you will have @Transactional etc Service layer annotations so hibernate treats it as a Service component.

Plus @Service is advance of @Component. Assume the bean class name is CustomerService, since you did not choose XML bean configuration way so you annotated the bean with @Component to indicate it as a Bean. So while getting the bean object CustomerService cust = (CustomerService)context.getBean("customerService"); By default, Spring will lower case the first character of the component – from 'CustomerService' to 'customerService'. And you can retrieve this component with name 'customerService'. But if you use @Service annotation for the bean class you can provide a specific bean name by

 @Service("AAA") public class CustomerService{ 

and you can get the bean object by

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