java - Spring中的@ Component,@ Repository和@Service注释有什么区别?
@Service,@Component和@Service注释可以在Spring中互换使用,或者它们除了作为符号设备之外还提供任何特定功能吗?
换句话说,如果我有一个Service类并且我将注释从@Service更改为@Component,它仍然会以相同的方式运行吗?
或者注释是否也会影响类的行为和功能?
24个解决方案
1212 votes
从Spring文档:
在Spring 2.0及更高版本中,@Repository注释是标记 任何履行角色或刻板印象的类(也称为数据 存储库的Access Object或DAO)。 这个标记的用途之一 是例外的自动翻译。
Spring 2.5引入了进一步的刻板印注:@Component, @Service和@Service. @Repository是一个通用的刻板印象 Spring管理的组件。 @Repository,@Service和@Controller是 @Component的特殊用途,用于更具体的用例 例如,在持久性,服务和表示层中, 分别。
因此,您可以使用@Component注释组件类, 但是用@Service,@Service或@Repository注释它们 相反,您的类更适合按工具处理 或与方面联系。 例如,这些刻板印象注释 为切入点制作理想的目标。
因此,如果您选择使用@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) │
└────────────┴─────────────────────────────────────────────────────┘
stivlo answered 2018-11-26T16:45:54Z
505 votes
由于许多答案已经说明了这些注释的用途,我们将在这里集中讨论它们之间的一些细微差别。
首先是相似性
值得再次强调的第一点是关于BeanDefinition的扫描自动检测和依赖注入所有这些注释(即@Component,@ Service, @ Repository,@ Controller)是一样的。 我们可以使用一个 另一个,仍然可以解决我的方式。
@ Component,@ Repository,@ Controller和@Service之间的差异
@零件
这是一个通用的构造型注释,表明该类是一个spring组件。
@Component有什么特别之处
@Service仅扫描@Controller并且一般不会寻找@Repository,@RequestMapping和@RequestMapping。 它们被扫描,因为它们本身用@Controller注释。
只需看看@Service,@Controller和@Repository注释定义:
@Component
public @interface Service {
….
}
@Component
public @interface Repository {
….
}
@Component
public @interface Controller {
…
}
因此,说@Service,@Controller和@Repository是特殊类型的@RequestMapping注释并没有错。 @RequestMapping选择它们并将以下类注册为bean,就像它们使用@Controller注释一样。
它们被扫描,因为它们本身用@Service注释进行注释。 如果我们定义自己的自定义注释并使用@Controller进行注释,那么它也将被扫描@Repository
@Repository
这是为了表明该类定义了一个数据存储库。
@Repository有什么特别之处?
除了指出这是一个基于注释的配置之外,@Service的工作是捕获平台特定的异常并将它们重新抛出为Spring的统一未经检查的异常之一。 为此,我们提供了@Controller,我们需要在Spring的应用程序上下文中添加如下:
此bean后处理器向任何使用@Service注释的bean添加一个顾问程序,以便捕获任何特定于平台的异常,然后将其作为Spring未经检查的数据访问异常之一重新抛出。
@Controller
@Service注释指示特定类充当控制器的角色。 @Controller注释充当带注释的类的构造型,指示其角色。
@Controller有什么特别之处?
我们无法将此注释与@Service或@Controller等任何其他注释切换,即使它们看起来相同。调度程序扫描用@Repository注释的类,并检测其中的@RequestMapping注释。 我们只能在@Controller注释类上使用@RequestMapping。
@服务
@Service在存储库层中保存业务逻辑和调用方法。
@Service有什么特别之处?
除了它用于表明它持有业务逻辑这一事实之外,这个注释没有明显的特点,但是谁知道,spring可能在未来增加一些额外的特殊功能。
还有什么?
与上面类似,将来Spring可能会根据它们的分层约定选择为@Service,@Controller和@Repository添加特殊功能。 因此,尊重惯例并将其与层一致使用始终是一个好主意。
Raman Sahasi answered 2018-11-26T16:48:08Z
400 votes
它们几乎相同 - 所有这些都意味着该类是一个Spring bean。 @ScheduledJob,@Service和@Controller是专用的@Components。 您可以选择使用它们执行特定操作。 例如:
spring-mvc使用了@ScheduledJob bean
@ScheduledJob bean有资格进行持久性异常转换
另一件事是你在语义上将组件指定给不同的层。
@ScheduledJob提供的一件事是您可以使用它注释其他注释,然后以与@Service相同的方式使用它们。
例如最近我做了:
@Component
@Scope("prototype")
public @interface ScheduledJob {..}
因此,所有使用@ScheduledJob注释的类都是spring bean,除此之外还注册为quartz作业。 您只需提供处理特定注释的代码即可。
Bozho answered 2018-11-26T16:48:55Z
340 votes
@Component相当于
@ Service,@ Controller,@ Repository = {@Component +一些更特殊的功能}
这意味着服务,控制器和存储库在功能上是相同的。
这三个注释用于分离应用程序中的“图层”,
控制器只是执行调度,转发,调用服务方法等操作。
服务保持业务逻辑,计算等。
存储库是DAO(数据访问对象),它们直接访问数据库。
现在您可能会问为什么将它们分开:(我假设你知道AOP-Aspect Oriented Programming)
假设您只想监视DAO层的活动。 您将编写一个Aspect(A类)类,在调用DAO的每个方法之前和之后执行一些日志记录,您可以使用AOP执行此操作,因为您有三个不同的层并且不会混合。
因此,您可以在DAO方法“周围”,“之前”或“之后”记录DAO。 你可以这样做,因为你首先有一个DAO。 您刚刚实现的是分离关注点或任务。
想象一下,如果只有一个注释@Controller,那么这个组件将具有调度,业务逻辑和访问数据库的所有混合,所以脏代码!
上面提到的是一个非常常见的场景,为什么要使用三个注释有更多的用例。
Oliver answered 2018-11-26T16:50:03Z
198 votes
在Spring @Component,@Service,@Controller和@Repository中是Stereotype注释,其用于:
@Component您的请求从演示文稿页面映射完成,即表示层将不会转到任何其他文件,它直接转到@Controller类,并检查@RequestMapping注释中的请求路径,如果需要,在方法调用之前写入。
@Component:所有业务逻辑都在这里,即与数据相关的计算和所有。这个业务层注释,我们的用户不直接调用持久性方法,因此它将使用此注释调用此方法。 它将根据用户请求请求@Repository
@Component:这是用于从数据库获取数据的应用程序的持久层(数据访问层)。 即所有与数据库相关的操作都由存储库完成。
@Component - 使用组件构造型注释您的其他组件(例如REST资源类)。
表示带注释的类是“组件”。 这类课程是 被认为是使用时自动检测的候选者 基于注释的配置和类路径扫描。
其他类级注释可以被视为标识a 组件也是一种特殊的组件:例如该 @Repository注释或AspectJ的@Aspect注释。
Harshal Patil answered 2018-11-26T16:50:51Z
62 votes
Spring 2.5引入了更多的构造型注释:@ Component,@ Service和@Controller。 @Component作为任何Spring管理组件的通用构造型;而@Repository,@ Service和@Controller用作更具体用例的@Component的特化(例如,分别在持久性,服务和表示层中)。这意味着您可以使用@Component注释组件类,但是通过使用@ Repository,@ Service或@Controller注释它们,您的类更适合通过工具处理或与方面关联。例如,这些刻板印象注释成为切入点的理想目标。当然,在Spring Framework的未来版本中,@ Repository,@ Service和@Controller也可能带有额外的语义。因此,如果您在为服务层使用@Component或@Service之间做出决定,那么@Service显然是更好的选择。同样,如上所述,已经支持@Repository作为持久层中自动异常转换的标记。
@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进行类路径扫描,托管组件和编写配置
Ajit Singh answered 2018-11-26T16:51:22Z
40 votes
从数据库连接的角度来看,使用@Repository和@Repository注释很重要。
对所有Web服务类型的数据库连接使用@Repository
对所有存储的proc DB连接使用@Repository
如果您不使用正确的注释,则可能会遇到由回滚事务覆盖的提交异常。 您将在压力负载测试期间看到与回滚JDBC事务相关的异常。
Das answered 2018-11-26T16:51:55Z
24 votes
@Repository @Service和@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.
atish shimpi answered 2018-11-26T16:52:15Z
23 votes
所有这些注释都是立体类型注释的类型,这三个注释之间的区别是
如果我们添加@Component然后它告诉class的类是一个组件类,它意味着它是一个包含一些逻辑的类,但它 不会告诉某个类是否包含特定的业务或 持久性或控制器逻辑,所以我们不直接使用它 @Component注释
如果我们添加@Service注释,那么它会告诉包含业务逻辑的类的角色
如果我们在类之上添加@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注释将存在于类的顶部
Anil Amane answered 2018-11-26T16:53:01Z
20 votes
从技术上讲,@ Controller,@ Service,@ Repository都是一样的。 所有这些都扩展了@Components。
来自Spring的源代码:
表示带注释的类是“组件”。 当使用基于注释的配置和类路径扫描时,这些类被视为自动检测的候选者。
我们可以直接对每个bean使用@Component,但是为了更好地理解和维护大型应用程序,我们使用@ Controller,@ Service,@ Repository。
每个注释的目的:
1)@Controller - > 用此注释的类旨在从客户端接收请求。 第一个请求来到Dispatcher Servlet,它使用@RequestMapping注释的值将请求传递给特定控制器。
2)@Service - > 用此注释的类旨在操作我们从客户端接收的数据或从数据库中获取的数据。 所有数据操作都应该在这一层完成。
3)@Repository - > 用此注释的类旨在与数据库连接。 它也可以被视为DAO(数据访问对象)层。 此层应仅限于CRUD(创建,检索,更新,删除)操作。如果需要任何操作,则应将数据发送回@Service层。
如果我们交换它们的位置(使用@Repository代替@Controller),我们的应用程序将正常工作。
使用三种不同的@annotations的主要目的是为企业应用程序提供更好的模块化。
Yogendra123 answered 2018-11-26T16:54:02Z
17 votes
Spring提供了四种不同类型的自动组件扫描注释,它们是@Repository,@Service,@Repository和@Controller.从技术上讲,它们之间没有区别,但是每个自动组件扫描注释应该用于特定目的并且在定义的层内。
@Repository:它是一个基本的自动组件扫描注释,它表示带注释的类是一个自动扫描组件。
@Repository:带注释的类表示它是控制器组件,主要用于表示层。
@Repository:它表示带注释的类是业务层中的服务组件。
@Repository:您需要在持久层中使用此批注,这类似于数据库存储库。
人们应该选择更专业的形式@Component,同时注释他们的类,因为这个注释可能包含未来的特定行为。
hardeep thakur answered 2018-11-26T16:54:44Z
16 votes
使用@Component注释其他组件,例如REST资源类。
@Component
public class AdressComp{
.......
...//some code here
}
@Component是任何Spring托管组件的通用构造型。
@ Controller,@ Service和@Repository是特定用例的@Component的特化。
春天的@Component
Anil Nivargi answered 2018-11-26T16:55:18Z
16 votes
我们可以根据java标准来回答这个问题
参考现在由spring支持的@RequestMapping,您只能使用@Controller来定义bean(Somehow @Named=@Component)。 所以根据这个标准,似乎没有用于定义类别bean的构造型(如@Repository,@Service,@Controller)。
但是弹簧用户将这些不同的注释用于特定用途,例如:
帮助开发人员为主管人员定义更好的类别。 在某些情况下,这种分类可能会有所帮助。 (例如,当您使用@RequestMapping时,这些可能是@Controller的良好候选者)
@RequestMapping注释将为您的bean添加一些功能(一些自动异常转换到您的bean持久层)。
如果您使用的是Spring MVC,则只能将@RequestMapping添加到由@Controller注释的类中。
Alireza Fattahi answered 2018-11-26T16:56:00Z
14 votes
在Spring 4中,最新版本:
@Repository注释是任何满足该类的类的标记 存储库的角色或构造型(也称为数据访问对象) 或DAO)。 这个标记的用途之一是自动翻译 第20.2.2节“异常转换”中描述的异常。
Spring提供了进一步的构造型注释:@ Component,@ Service, 和@Controller。 @Component是任何的通用构造型 Spring管理的组件。 @ Repository,@ Service和@Controller是 对于更具体的用例,@ Component的特化 例如,在持久性,服务和表示层中, 分别。因此,您可以使用注释对组件类进行注释 @Component,但是用@ Repository,@ Service或者注释它们 @Controller相反,你的类更适合 通过工具处理或与方面相关联。例如,这些 刻板印注是切入点的理想目标。也是 可能是@ Repository,@ Service和@Controller可以携带 Spring框架的未来版本中的其他语义。从而, 如果您选择使用@Component或@Service作为您的 服务层,@ Service显然是更好的选择。同样,如 如上所述,已经支持@Repository作为标记 持久层中的自动异常转换。
Quan Nguyen answered 2018-11-26T16:56:31Z
13 votes
即使我们交换@Component或@Repository或@service
它的行为相同,但有一个方面是,如果我们使用组件或@服务,它们将无法捕获与DAO相关的特定异常而不是Repository
Manjush answered 2018-11-26T16:56:56Z
11 votes
@ Component,@ Service,@ Controller,@ Repository之间没有区别。@Component是表示MVC组件的Generic注释。 但是,作为MVC应用程序的一部分,将有几个组件,如服务层组件,持久层组件和表示层组件。 所以要区分它们Spring人们也给了其他三个注释。
表示持久层组件:@Repository
表示服务层组件:@Service
表示表示层组件:@Controller
否则你可以将@Component用于所有这些。
tech.yenduri answered 2018-11-26T16:57:34Z
8 votes
一个Repository引用spring文档,
表示带注释的类是最初定义的“服务” 通过领域驱动设计(Evans,2003)作为“作为一个提供的操作 在模型中独立的接口,没有封装状态。“ 也可能表明一个班级是“商业服务门面”(在 核心J2EE模式感觉)或类似的东西。 这个注释是一个 通用刻板印象和个人团队可以缩小他们的范围 语义和适当的使用。
如果你看看eric evans的域驱动设计,
服务是作为独立的接口提供的操作 模型,没有封装状态,作为ENTITIES和VALUE OBJECTS 做。服务是技术框架中的常见模式,但它们 也可以在域层中应用。名称服务强调 与其他对象的关系。它与ENTITIES和VALUE OBJECTS不同 纯粹根据它可以为客户做什么来定义。服务 往往以活动命名,而不是实体 - 动词 而不是名词。服务仍然可以有意图的抽象 定义;它只是有一种不同于a的定义的味道 宾语。服务部门仍然应该有明确的责任 责任和履行它的界面应定义为 域模型的一部分。操作名称应来自 UBIQUITOUS LANGUAGE或被引入其中。参数和结果 应该是域对象。服务应该谨慎使用而不是 允许剥夺他们所有行为的ENTITIES和VALUE OBJECTS。 但是当一个操作实际上是一个重要的领域概念时,a SERVICE是MODEL-DRIVEN DESIGN的自然组成部分。宣告在 模型作为服务,而不是作为一个没有的虚假对象 实际上代表什么,独立操作不会误导 任何人。
和Eric Evans的Repository,
REPOSITORY将某种类型的所有对象表示为概念 设置(通常是模拟的)。 它的作用就像一个集合,除了更多 精心设计的查询功能。 适当类型的对象是 添加和删除,以及REPOSITORY插入后面的机器 他们或从数据库中删除它们。 这个定义收集了一个 提供访问根源的一致的责任 从早期生命周期到结束聚集。
Bharath answered 2018-11-26T16:58:19Z
8 votes
@RequestMapping是顶级通用注释,它使得带注释的bean在DI容器中被扫描并可用
@RequestMapping是专门的注释,它带来了从DAO类转换所有未经检查的异常的功能
@RequestMapping是专门的注释。 它现在没有带来任何新功能,但它澄清了bean的意图
@Controller是专门的注释,它使bean知道MVC并允许使用更多注释,如@RequestMapping等所有这些
这里有更多细节
Amol Dixit answered 2018-11-26T16:58:57Z
8 votes
@Component:你注释一个类@Component,它告诉hibernate它是一个Bean。
@Repository:你注释一个类@Repository,它告诉hibernate它是一个DAO类并将其视为DAO类。 意味着它使未经检查的异常(从DAO方法抛出)有资格转换为Spring DataAccessException。
@Service:这告诉hibernate它是一个Service类,你将拥有@Transactional等服务层注释,因此hibernate将其视为服务组件。
加上@Service是@Component的进步。 假设bean类名称是CustomerService,因为您没有选择XML bean配置方式,因此您使用@Component对bean进行注释以将其指示为Bean。 因此,在获取bean对象CustomerService cust = (CustomerService)context.getBean("customerService");时,默认情况下,Spring会将组件的第一个字符 - 从“CustomerService”更改为“customerService”。 您可以使用名称“customerService”检索此组件。但是如果对bean类使用@Service注释,则可以提供特定的bean名称
@Service("AAA")
public class CustomerService{
你可以通过获取bean对象
CustomerService cust = (CustomerService)context.getBean("AAA");
Arun Raaj answered 2018-11-26T16:59:36Z
3 votes
刻板印象的解释:
@Component - 使用@Service注释所有服务类。 该层知道工作单元。 您的所有业务逻辑都将在Service类中。 通常,服务层的方法包含在事务中。 您可以从服务方法进行多个DAO调用,如果一个事务失败,则所有事务都应该回滚。
@Component - 使用@Repository注释所有DAO类。 您的所有数据库访问逻辑都应该在DAO类中。
@Component - 使用组件构造型注释您的其他组件(例如REST资源类)。
@Component - 让Spring使用@Autowired注释将其他bean自动连接到您的类中。
@Component是任何Spring管理的组件的通用构造型。 @Repository,@Service和@Controller是@Component的特化,用于更具体的用例,例如,分别在持久性,服务和表示层中。
原来这里回答。
Jeevan Patil answered 2018-11-26T17:00:23Z
2 votes
存储库和服务是组件注释的子级。 所以,所有这些都是组件。 存储库和服务只是扩展它。究竟怎么样?服务只有意识形态上的差异:我们将其用于服务。 存储库有特殊的异常处理程序。
Maria Karpikova answered 2018-11-26T17:00:44Z
1 votes
@Component,@ Repository,@ Service,@ Controller:
@Component是由Spring @ Repository管理的组件的通用构造型,@ Service和@Controller是@Component特化,用于更具体的用途:
@Repository用于持久化
@Service服务和交易
@Controller用于MVC控制器
为什么在@Component上使用@ Repository,@ Service,@ Controller?我们可以使用@Component标记我们的组件类,但是如果我们使用适应预期功能的替代方法。 我们的类更适合于每种特定情况下的预期功能。
使用“@Repository”注释的类使用org.springframework.dao.DataAccessException具有更好的转换和可读错误处理。 非常适合实现访问数据的组件(DataAccessObject或DAO)。
带有“@Controller”的带注释的类在Spring Web MVC应用程序中扮演控制器角色
带有“@Service”的带注释的类在业务逻辑服务中起作用,例如DAO Manager(Facade)的Facade模式和事务处理
UHDante answered 2018-11-26T17:01:40Z
1 votes
在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.
上面声明的注释是特殊的,因为当我们将添加到xxx-servlet.xml文件中时,spring将自动创建在上下文创建/加载阶段使用上述注释注释的那些类的对象。
Brajesh answered 2018-11-26T17:02:05Z
-2 votes
@component
@controller
@Repository
@service
@RestController
这些都是StereoType注释。 如果我们把@controller放在课堂上。 它不会成为基于我们可以用这个注释注释的不同层(组件)的控制器类,但编译器不会对此做任何事情只是为了开发人员的理解目的我们可以根据我们必须编写的注释组件进行选择
siddartha kamble answered 2018-11-26T17:02:25Z