Spring中的@Component、@Reposaku和@Service注释有什么区别?

#0#1#2注释可以在Spring中互换使用吗?或者它们除了充当符号设备之外还提供任何特定的功能吗?

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

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

1085623 次浏览

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

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

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

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

例如,最近我做了:

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

因此,所有使用@ScheduledJob注释的类都是Spring bean,此外还注册为石英作业。您只需提供处理特定注释的代码。

Spring文档

@Repository注释是任何满足存储库的角色或原型(也称为数据访问对象)或DAO)。此标记的用途之一是自动翻译异常,如翻译例外中所述。

Spring提供了进一步的原型注释:@Component@Service@Controller@Component是任何类型的通用刻板印象Spring管理的组件。@Repository@Service@Controller@Component的专业化用于更具体的用例(在分别为持久化层、服务层和表示层)。因此,您可以使用@Component注释您的组件类,但是,通过用@Repository@Service@Controller注释它们相反,您的类更适合用工具处理或与方面联系。

例如,这些原型注释为切入点制作理想的目标。@Repository@Service@Controller还可以在未来的版本中携带额外的语义学Spring框架。因此,如果您在使用@Component@Service对于您的服务层,@Service显然是更好的选择。同样,如前所述,@Repository已经是支持作为自动异常转换的标记持久层。

注释含义
@Component任何Spring托管组件的通用原型
@Repository持久层原型
@Service服务层原型
@Controller表示层的原型(sping-mvc)

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

  1. 对所有Web服务类型的DB连接使用@Service
  2. 对所有存储的proc DB连接使用@Repository

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

Spring 2.5引入了进一步的原型注释:@Component、@Service和@Controller。@Component作为任何Spring托管组件的通用原型;而@Repostory、@Service和@Controller作为@Component的特化,用于更具体的用例(例如,分别在持久化层、服务层和表示层)。这意味着你可以用@Component注释你的组件类,但是通过使用@Reposary、@Service或@Controller注释它们,你的类更适合通过工具处理或与方面关联。例如,这些原型注释是切入点的理想目标。当然,@Reposential、@Service和@Controller也有可能在Spring Framework的未来版本中携带额外的语义学。因此,如果您在服务层使用@Component或@Service之间做出决定,@Service显然是更好的选择。类似地,如上所述,@Reposential已经被支持作为持久层中自动异常转换的标记。

@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扫描类路径、托管组件和编写配置

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

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

在Spring@Component@Service@Controller@Repository中,刻板印象注释用于:

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

@Service:所有的业务逻辑都在这里,即数据相关的计算和所有。

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

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

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

其他类级注释可以被认为是识别组件也是,通常是一种特殊类型的组件:例如@存储库注释或A的@Aspect注释。

在此处输入图片描述

@Component等价于

<bean>

@服务,@控制器,@存储库={@组件+一些更特殊的功能}

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

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

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

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

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

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

想象一下,如果只有一个注释@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.

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

  • 如果我们添加@Component,那么它告诉类的角色是一个组件类,这意味着它是一个包含一些逻辑的类,但它是一个组件类不知道一个类是否包含一个特定的业务或持久性或控制器逻辑,所以我们不直接使用这个@组件标注
  • 如果我们添加@Service注释,那么它会告诉一个由业务逻辑组成的类的角色
  • 如果我们在类的顶部添加@Reposaku,那么它会告诉一个由持久性逻辑组成的类
  • 这里@Component是@Service、@Reposential和@Controller注释的基本注释

例如

package com.spring.anno;@Servicepublic class TestBean{public void m1(){//business code}}
package com.spring.anno;@Repositorypublic class TestBean{public void update(){//persistence code}}
  • 每当我们添加@Service@Repositroy@Controller注释时,默认情况下@Component注释将存在于类的顶部

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

  • 表示持久层组件:@Repository
  • 表示服务层组件:@Service
  • 表示表示层组件:@Controller
  • 否则,您可以对所有这些都使用@Component

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

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

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

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

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

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

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

参考JSR-330,现在Spring支持,你只能使用@Named来定义一个bean(不知何故@Named=@Component)。所以根据这个标准,似乎没有必要定义刻板印象(如@Repository@Service@Controller)来分类bean。

但是Spring user这些不同的注释针对具体用途不同,例如:

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

在Spring 4中,最新版本:

@存储库注释是任何满足存储库的角色或原型(也称为数据访问对象)或DAO)。此标记的用途之一是自动翻译如第20.2.2节“异常转换”中所述的异常。

Spring提供了进一步的原型注释:@Component、@Service、和@Controller。@Component是任何Spring管理的组件。@Repostory、@Service和@Controller是@Component的专业化用于更具体的用例,用于例如,在持久性、服务和表示层中,因此,您可以使用@组件,但通过使用@Reposential、@Service或@Controller相反,你的类更适合通过工具处理或与方面关联。例如,这些原型注释是切入点的理想目标@Reposential、@Service和@Controller可能携带Spring框架未来版本中的附加语义学。因此,如果您在使用@Component或@Service之间进行选择服务层,@Service显然是更好的选择。同样,作为如上所述,@Repostory已经被支持作为持久层中的自动异常转换。

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

首先是相似性

值得再次强调的第一点是关于BeanCustition的扫描自动检测和依赖注入所有这些注释(即@Component、@Service、#36825;,还能绕道而行。


@组件、@存储库、@控制器和@服务之间的区别

@陈子强

这是一个通用的原型注释,表明该类是一个Spring组件。

@Component有什么特别之处
<context:component-scan>只扫描@Component,通常不查找@Controller@Service@Repository。它们被扫描是因为它们本身被@Component注释了。

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

@Componentpublic @interface Service {….}

 

@Componentpublic @interface Repository {….}

 

@Componentpublic @interface Controller {…}

因此,说@Controller@Service@Repository@Component注释的特殊类型并没有错。<context:component-scan>选择它们并将它们的以下类注册为bean,就好像它们被@Component注释一样。

特殊类型的注释也会被扫描,因为它们本身被@Component注释注释,这意味着它们也是@Component。如果我们定义自己的自定义注释并用@Component注释,它也会被<context:component-scan>扫描


@代码库

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

@存储库有什么特别之处?

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

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

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


@刘振华

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

控制器有什么特别之处?

我们不能将此注释与任何其他注释(如@Service@Repository)切换,即使它们看起来相同。调度程序扫描带有@Controller注释的类并检测其中带有@RequestMapping注释的方法。我们只能在那些类带有@Controller注释的方法上使用@RequestMapping,它将不是@Component一起使用,@Service@Repository等…

注意:如果一个类已经通过任何替代方法注册为bean,比如通过@Bean或通过@Component@Service等…注释,那么如果该类也使用@RequestMapping注释,则可以选择@RequestMapping。但这是一个不同的场景。


@刘志强

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

服务有什么特别之处?

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


还有什么?

类似于上面,未来Spring可能会根据@Service@Controller@Repository的分层约定为它们添加特殊的功能。因此,尊重约定并根据层使用它总是一个好主意。

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

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

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

@Controller是专门的注释,它使bean MVC感知并允许使用@RequestMapping等进一步的注释

更多细节

A@Service引用春留档,

表示带注释的类是最初定义的“Service”由领域驱动设计(Evans,2003)作为“作为在模型中独立存在的接口,没有封装状态。"也可以表明一个类是一个“Business Service Facade”(在核心J2EE模式意义),或类似的东西。这个注释是一个通用刻板印象和个别团队可能会缩小他们的语义学和适当的使用。

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

服务是作为接口提供的操作,它独立于模型,没有封装状态,作为实体和值对象服务是技术框架中的一种常见模式,但它们也可以应用于域层。名称服务强调与其他对象的关系。与实体和价值对象不同,它是纯粹根据它能为客户做什么来定义的。服务往往被命名为一个活动,而不是一个实体-一个动词而不是一个服务仍然可以有一个抽象的,故意的定义;它只是有一个不同的味道比的定义对象。服务仍应具有定义的责任,并且责任和履行责任的接口应定义为域模型的一部分。操作名称应来自通用语言或被引入其中。参数和结果应该是域对象。服务应该明智地使用,而不是允许剥夺实体和价值对象的所有行为。但是当一个操作实际上是一个重要的领域概念时,一个服务是模型驱动设计的自然组成部分作为服务建模,而不是作为一个虚假的对象实际上代表任何东西,独立操作不会误导任何人。

和一个Repository根据埃里克·埃文斯,

REPOSITORY将特定类型的所有对象表示为概念集合(通常是模拟的)。它的行为就像一个集合,除了更多详细的查询能力。适当类型的对象是添加和删除,以及存储后面的机器插入它们或从数据库中删除它们。此定义收集了一个一整套有凝聚力的责任,以提供对从生命周期的早期到结束。

这些是刻板印象注释,自动扫描的候选者

从技术上讲,@Controller@Service@Repository都是一样的。它们都延伸了@Component

来自Spring源代码:

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

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

每个注释的目的:

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

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

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

@陈子强:你注释一个类@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默认情况下会将组件的第一个字符小写-从“CustmerService”到“CusterService”。您可以使用名称“CusterService”检索此组件。但是如果您对bean类使用@Service注释,您可以通过

提供特定的bean名称
@Service("AAA")public class CustomerService{

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

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

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

@Componentpublic class AdressComp{..........//some code here}

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

@Controller、@Service和@Reposential是@Component针对特定用例的专业化。

@陈志立

组件专业化

刻板印象的解释:

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

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

最初回答这里

@Component@ Repository@ Service@Controller

@Component是Spring@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 Manager(Facade)的示例Facade模式和事务处理

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

@Component@Controller@Repository@Service@RestController

这些都是StereoTypeannotations.this对于将我们的类作为ioc容器中的Spring bean是有用的,

存储库服务组件注释的子代。所以,它们都是组件存储库服务只是展开它。具体怎么做?Service只有意识形态上的区别:我们将其用于服务。存储库有特定的异常处理程序。

为了简化这个例子,让我们考虑用例的技术性,这些注释是用来注入的,正如我字面上所说的“以前是注射的”,这意味着,如果你知道如何使用依赖注入“DI”并且你应该,那么你将总是寻找这些注释,通过用这些立体声类型注释类,你正在通知DI容器扫描它们以准备在其他地方注入,这是实际的目标。

现在让我们移动到每一个;第一@Service,如果您正在为特定的业务案例构建一些逻辑,您需要将其分离到一个包含您的业务逻辑的地方,此服务是普通类,或者如果您愿意,您可以将其用作接口,它是这样写的

@Servicepublic class Doer {// Your logic}

要在另一个类中使用它,假设在Controller中

@Controllerpublic class XController {// You have to inject it like this@Autowiredprivate Doer doer;
// Your logic}

注入它们的方式都是一样的,@Repository是一个应用存储库模式存储库设计模式实现的接口,通常当你处理一些数据存储或数据库时使用,你会发现,它包含多个现成的实现供你处理数据库操作;它可以是CrudRepositoryJpaRepository等。

例如:

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

最后是@Component,这是Spring中注册bean的通用形式,即Spring总是在寻找标记为@Component的bean进行注册,然后@Service@Repository都是@Component的特殊情况,然而组件的常见用例是当您制作纯技术的东西时不包括直接业务案例!比如格式化日期或处理特殊请求序列化机制等等。

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

#0 vs#1

#0

在此处输入图片描述

  • 这个注释是@Controller的一个特殊版本,它增加了@Controller@ResponseBody自动注释。所以我们不必将@ResponseBody添加到我们的映射方法中。这意味着@ResponseBody是默认的活动状态。
  • 如果使用@RestController,则无法返回视图(通过使用Viewresolver in Spring/Spring-Boot)
  • @RestController还将响应转换为JSON/XML automatically,因为@ResponseBody使返回的对象成为可能在主体中的东西,e.g. JSON or XML

@Controller

在此处输入图片描述

  • @Controller用于将类标记为Spring MVC控制器。这注解只是@Component的一个特殊版本,它允许基于类路径自动检测控制器类扫描。
  • @Controller你可以在Spring web MVC中返回一个视图。

查看更多详细信息

@组件、@存储库、@控制器和@服务注释之间的区别

@Component-通用的,可以跨应用程序使用。
@服务-在服务层级别注释类。
@Controller-注释表示层级别的类,主要用于Spring MVC。
@存储库-在持久层注释类,这将充当数据库存储库。

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

@陈子强在配置类中充当@Bean注释,在Spring上下文中注册bean。它也是@Service、@Reposential和@Controller注释的父级。

@刘志强,扩展了@Component注释并且只有命名差异。

@代码库-扩展@Component注释并将所有数据库异常转换为是否必选数据异常.

@刘振华-在MVC模式中充当控制器。调度程序将扫描此类带注释的类以查找映射方法,检测@Request estMping注释。

这里给出的答案部分在技术上是正确的,但即使响应列表很长,这将是底部我认为值得在这里放一个真正正确的响应,以防有人偶然发现它并从中学到一些有价值的东西。并不是说其余的答案是完全错误的,只是它们不对。而且,为了阻止成群的巨魔,是的,我知道从技术上讲,这些注释现在实际上是同样的事情,甚至到春天5,大部分都是可以互换的。现在,为了正确的答案:

这三个注释是完全不同的东西,是不可互换的。你可以看出,因为它们有三个,而不仅仅是一个。它们不是可以互换的,它们只是出于优雅和方便而实现的。

现代编程包含了发明、艺术、技术和交流。交流这一块通常很重要,因为读的人比写的人多。作为一个程序员,你不仅要解决技术问题,还要把你的意图传达给未来读你代码的程序员。未来的程序员可能和你母语不一样,社交环境也不相同,有可能50年后他们也会读你的代码(这并不像你想象的那么不可能)。在那么遥远的未来,要想有效地沟通是很困难的。因此,我们使用最清晰、最高效、正确和交流的语言至关重要。我们仔细选择了我们的话,以产生最大的影响,并尽可能清楚地表达我们的意图。

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

我不会深入其他例子,但会尽可能清楚地说明:这些注释是完全不同的东西,应该根据它们的意图适当地使用。@Repository用于存储存储库,没有其他注释是正确的。@Service用于服务,没有其他注释是正确的。@Controller用于既不是存储库也不是服务的组件,使用这两者中的任何一个代替它也是不正确的。它可能会编译,它甚至可能运行并通过你的测试,但这将是错误的,如果你这样做,我会降低你(专业)的评价。

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

最后想提一个关于面向对象系统的逻辑问题。这个有一条基本规则,就是实现可以变,但是接口不能变。假设这些标注是一样的东西是非常危险的,这是完全违背OO的。尽管它们现在可能以一种可互换的方式实现,但不能保证将来一定可以。此外,即使在同一个团队中,工程师也可能决定使用方面来挂起一个或多个这些标注的行为,或者平台工程师出于操作原因选择替换其中一个标注的实现。你只是不知道,也不应该知道——在OO中,你依赖接口,而不是实现。

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

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

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

在此处输入图片描述


@组件vs@存储库vs@服务


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

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

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

@组件标注

我们可以在整个应用程序中使用@Component来将bean标记为Spring的托管组件。Spring只会使用@Component获取和注册bean,通常不会寻找@Service和@Repostory。

它们在Application ationContext中注册,因为它们被@Component注释

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

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Indexedpublic @interface Component {String value() default "";}

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

@服务说明

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

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

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Service {@AliasFor(annotation = Component.class)String value() default "";}

@代码库注解

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

为此,Spring提供了PersidenceExceptionTranslationPostProc的,我们需要在我们的应用程序上下文中添加它(如果我们使用Spring Boot,已经包括在内):

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

这个bean后处理器为任何使用@Reposaku注释的bean添加了一个顾问。

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

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Repository {@AliasFor(annotation = Component.class)String value() default "";}

总结

@Service和@Repostory是@Component的特例。它们在技术上是相同的,但我们将它们用于不同的目的。