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

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

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


当前回答

@组件、@Repository、@Service、@Controller:

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

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

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

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

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

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

其他回答

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

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

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

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

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

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

它们几乎相同——所有这些都意味着这个类是一个Spring bean@Service、@Repository和@Controller是专门的@Components。您可以选择与他们一起执行特定操作。例如:

@springmvc使用控制器bean@存储库bean有资格进行持久性异常转换

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

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

例如,最近我做了:

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

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

@组件等效于

<bean>

@服务,@Controller,@Repository={@Component+一些更特殊的功能}

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

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

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

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

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

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

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

上面提到的是一个非常常见的场景,还有很多使用三个注释的用例。

A@Service引用spring文档,

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

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

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

以及根据Eric Evans,

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

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

首先是相似性值得再次强调的第一点是,关于扫描自动检测和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添加特殊功能。因此,尊重惯例并按照层使用它总是一个好主意。