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

问题

Can@Component,@Repository@Service注释可以在Spring中互换使用,还是除了作为符号设备之外还提供任何特定功能?

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

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


#1 热门回答(1150 赞)

FromSpring Documentation

在Spring 2.0及更高版本中,@ Repository注释是任何满足存储库的角色或构造型(也称为数据访问对象或DAO)的类的标记。该标记的用途之一是异常的自动转换。 Spring 2.5引入了更多的构造型注释:@ Component,@ Service和@Controller。 @Component是任何Spring管理组件的通用构造型。 @Repository,@ Service和@Controller是@Component的特化,用于更具体的用例,例如,分别在持久性,服务和表示层中。因此,你可以使用@Component注释组件类,但是通过使用@ Repository,@ Service或@Controller注释它们,你的类更适合通过工具处理或与方面关联。例如,这些刻板印象注释成为切入点的理想目标。因此,如果你选择在服务层使用@Component或@Service,@ Service显然是更好的选择。同样,如上所述,已经支持@Repository作为持久层中自动异常转换的标记。

┌────────────┬─────────────────────────────────────────────────────┐
│ 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)      │
└────────────┴─────────────────────────────────────────────────────┘

#2 热门回答(446 赞)

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

首先,值得强调的相似性第一点是,对于BeanDefinition的扫描自动检测和依赖注入,所有这些注释(即@ Component,@ Service,@ Repository,@ Controller)都是相同的。我们可以使用一个代替另一个,仍然可以解决问题。

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

@Component

这是一个通用的构造型注释,表明该类是一个spring组件。

@Component有什么特别之处
<context:component-scan>only扫描@Component并且一般不寻找@Controller,@Service@Repository。扫描它们是因为它们本身用@Component注释。

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

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

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

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

@Repository

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

@Repository有什么特别之处?

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

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

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

@Controller

@Controllerannotation指示特定类充当控制器的角色。 The@Controllerannotation充当带注释的类的构造型,指示其角色。

@Controller有什么特别之处?

我们无法将此注释与其他任何类似的@Service@Repository切换,即使它们看起来相同。调度程序扫描用@Controller注释的类,并检测其中的@RequestMapping个注释。我们只能使用@RequestMappingon@Controller注释类。

@Service

@Services保留存储库层中的业务逻辑和调用方法。

@Service有什么特别之处?

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

还有什么?

与上面类似,将来Spring可能会根据它们的分层约定选择为@Service,@Controller@Repository添加特殊功能。因此,尊重惯例并将其与层一致使用始终是一个好主意。


#3 热门回答(392 赞)

它们几乎相同 - 所有这些都意味着该类是一个Spring bean.@Service,@Repository@Controller是special@Components。你可以选择使用它们执行特定操作。例如:

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

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

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

例如最近我做了:

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

因此,所有注释为@ScheduledJob的类都是spring bean,除此之外还注册为quartz作业。你只需提供处理特定注释的代码即可。