@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?

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

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


当前回答

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

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

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

@控制器是专门的注释,它使bean MVC意识到,并允许使用进一步的注释,如@RequestMapping等

以下是更多详细信息

其他回答

@Component
@Controller
@Repository
@Service
@RestController

这些都是StereoType注释。这对于在ioc容器中将我们的类制作为springbean非常有用,

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

@Controller:在完成了来自演示页面的请求映射的地方,即演示层不会转到任何其他文件,它会直接转到@Controller类,并在@RequestMapping注释中检查请求的路径,如果需要,该注释在方法调用之前编写。

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

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

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

指示带注释的类是“组件”。此类类为使用时被视为自动检测的候选项基于注释的配置和类路径扫描。其他类级别注释可被视为标识组件,通常是一种特殊类型的组件:例如@Repository注解或AspectJ的@Aspect注解。

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

首先是相似性值得再次强调的第一点是,关于扫描自动检测和BeanDefinition的依赖注入,@Repository、@Controller)是相同的。我们可以就地使用另一个的,仍然可以得到我们的方式。


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

@组件

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

@Component有什么特别之处<context:componentscan>仅扫描@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:componentscan>拾取它们并将它们的以下类注册为bean,就像它们用@component注释一样。

特殊类型注释也会被扫描,因为它们本身是用@Component注释注释的,这意味着它们也是@Components。如果我们定义自己的自定义注释并使用@Component对其进行注释,那么它也将通过<context:componentscan>进行扫描


@存储库

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

@Repository有什么特别之处?

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

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

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


@控制器

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

@Controller有什么特别之处?

我们无法将此注释与任何其他注释(如@Service或@Repository)切换,即使它们看起来相同。分派器扫描用@Controller注释的类,并检测其中用@RequestMapping注释注释的方法。我们只能在类用@Controller注释的方法上/中使用@RequestMapping,它不能与@Component、@Service、@Repository等一起使用。。。

注意:如果一个类已经通过任何替代方法注册为bean,例如通过@bean或通过@Component、@Service等注释,那么如果该类也使用@RequestMapping注释进行注释,则可以选择@RequestMapping。但情况不同。


@服务

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

@Service有什么特别之处?

除了它用来表示,它持有业务逻辑之外,这个注释中没有其他值得注意的地方;但谁知道呢,Spring可能会在未来增加一些额外的例外。


还有什么?

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

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

@服务,扩展了@Component注释,只有命名差异。

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

@控制器-在MVC模式中充当控制器。分派器将扫描这些带注释的类以查找映射方法,检测@RequestMapping注释。

A@Service引用spring文档,

指示带注释的类是最初定义的“服务”被领域驱动设计(Evans,2003)称为“接口在模型中独立,没有封装状态。"也可以表示类是“业务服务外观”(在核心J2EE模式感觉)或类似的东西。此注释是通用刻板印象和单个团队可能会缩小语义并酌情使用。

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

SERVICE是作为独立于模型,没有封装状态,作为ENTITIES和VALUE OBJECTS服务是技术框架中的一种常见模式,但它们也可以应用于域层。名称服务强调与其他对象的关系。与实体和价值对象不同纯粹是根据它可以为客户做什么来定义的。服务倾向于以活动而非实体命名,而不是动词而不是名词。SERVICE仍然可以具有抽象的、故意的释义它只是有一种不同于对象服务仍应具有明确的责任责任和履行责任的接口应定义为域模型的一部分。操作名称应来自通用语言或被引入其中。参数和结果应该是域对象。应明智地使用服务,而不是允许删除实体和值对象的所有行为。但当一个操作实际上是一个重要的领域概念时服务是模式驱动设计的自然组成部分。声明于将模型作为一种服务,而不是作为一个假的对象实际上,独立操作不会误导任何人任何人

以及根据Eric Evans,

REPOSTORY将特定类型的所有对象表示为概念对象设置(通常是模拟的)。它就像一个集合,除了有更多详细的查询功能。适当类型的对象包括添加和删除,以及REPOSTORY插件后面的机械或从数据库中删除它们。此定义收集了提供访问根从生命周期早期到生命周期结束的聚集。