@Repository
@Component
, @Repository
和@Service
批注可以在Spring中互换使用吗,或者除了充当注解设备外,它们还提供任何特定功能吗?
换句话说,如果我有一个Service类,并且将注释从@Service
更改为@Component
,它的行为是否仍将相同?
还是注释也会影响类的行为和功能?
#1楼
使用@Service
和@Repository
注解是从数据库连接的角度很重要。
- 将
@Service
用于所有Web服务类型的数据库连接 - 对所有存储的proc DB连接使用
@Repository
如果未使用正确的注释,则可能会遇到由回滚事务覆盖的提交异常。 在压力负载测试期间,您将看到与回滚JDBC事务相关的异常。
#2楼
Spring 2.5引入了更多的构造型注释:@ Component,@ Service和@Controller。 @Component用作任何Spring托管组件的通用构造型; 而@ Repository,@ Service和@Controller作为@Component的特殊化,用于更具体的用例(例如,分别在持久性,服务和表示层中)。 这意味着您可以使用@Component来注释组件类,但是通过使用@ Repository,@ Service或@Controller来注释它们,您的类更适合于通过工具进行处理或与方面相关联。 例如,这些构造型注释成为切入点的理想目标。 当然,@ Repository,@ Service和@Controller也有可能在Spring框架的未来版本中带有其他语义。 因此,如果您决定在服务层使用@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进行类路径扫描,托管组件和编写配置
#3楼
即使我们互换@Component或@Repository或@service
它将具有相同的行为,但是一方面是,如果我们使用component或@ service,它们将无法捕获与DAO而不是存储库相关的某些特定异常。
#4楼
在Spring中, @Service
@Component
, @Service
@Controller
, @Repository
@Controller
和@Repository
是@Repository
型注释,用于:
@Controller:
从表示页面完成的请求 映射即表示层不会转到任何其他文件,它将直接转到@Controller
类并检查@RequestMapping
注释中的请求路径,该注释在必要时在方法调用之前编写。
@Service
:所有业务逻辑都在这里,即与数据相关的计算和所有。业务层的此批注,我们的用户没有直接调用持久性方法,因此它将使用此批注来调用此方法。 它将根据用户请求请求@Repository
@Repository
:这是应用程序的持久层(数据访问层),用于从数据库中获取数据。 即所有与数据库有关的操作都由存储库完成。
@Component
Component-用组件@Component
注释其他组件(例如REST资源类)。
指示带注释的类是“ 组件 ”。 当使用基于注释的配置和类路径扫描时,此类会被视为自动检测的候选。
其他类级注释也可以被视为标识组件,通常是一种特殊的组件:例如@Repository注释或AspectJ的@Aspect注释。
#5楼
@Component等效于
<bean>
@ Service,@ Controller,@ Repository = {@Component +一些其他特殊功能}
这意味着服务,控制器和存储库在功能上是相同的。
这三个注释用于在应用程序中分隔“层” ,
- 控制器只是执行诸如调度,转发,调用服务方法之类的工作。
- 服务保留业务逻辑,计算等
- 存储库是DAO(数据访问对象),它们直接访问数据库。
现在您可能会问为什么将它们分开:(我假设您知道面向AOP的面向程序设计)
假设您只想监视DAO层的活动。 您将编写一个Aspect(A类)类,该类在调用DAO的每个方法之前和之后进行一些日志记录,因为您具有三个不同的层并且没有混合在一起,所以可以使用AOP进行记录。
因此,您可以在DAO方法“前后”,“之前”或“之后”记录DAO。 之所以可以这样做,是因为您首先拥有了一个DAO。 您刚刚实现的是关注点或任务分离。
想象一下,如果只有一个@Controller注释,那么此组件将具有调度,业务逻辑和访问数据库的所有混合功能,因此代码很脏!
上面提到的是一种非常常见的场景,为什么要使用三个注释还有更多的用例。
#6楼
@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.
#7楼
所有这些注释都是立体类型的注释类型,这三个注释之间的区别是
- 如果我们添加@Component,则它告诉类的角色是组件类,这意味着它是由某种逻辑组成的类,但是它不能告诉类是否包含特定的业务或持久性或控制器逻辑,因此我们不使用直接将此@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
注释将存在于类顶部
#8楼
@ Component,@ Service,@ Controller,@ Repository之间没有区别。 @Component是表示我们MVC组件的通用注释。 但是,作为我们MVC应用程序的一部分,将有几个组件,例如服务层组件,持久层组件和表示层组件。 因此,为了区分它们,Spring人们还给出了其他三个注释。
表示持久层组件:@Repository
表示服务层组件:@Service
表示表示层组件:@Controller
否则,您可以对所有它们使用@Component。
#9楼
Spring提供了四种不同类型的汽车零部件扫描注释,它们是@Component
, @Service
, @Repository
和@Controller
。 从技术上讲,它们之间没有区别,但是每个自动组件扫描注释都应用于特定目的并在定义的层内使用。
@Component
:这是一个基本的自动组件扫描注释,它指示带注释的类是一个自动扫描组件。
@Controller
:带注释的类表明它是控制器组件,主要在表示层使用。
@Service
:它指示带注释的类是业务层中的Service组件。
@Repository
:您需要在持久层中使用此批注,这就像数据库存储库。
在注释其类时,应该选择一种更特殊的@Component
形式,因为此注释可能包含特定的行为。
#10楼
我们可以根据java标准来回答
参照Spring现在支持的JSR-330
,您只能使用@Named
定义一个bean(Somehow @Named=@Component
)。 因此,根据该标准,似乎没有用来定义对bean进行分类的@Repository
型(例如@Repository
, @Service
@Repository
, @Service
@Controller
)。
但是弹簧用户将这些不同的注释以不同的特定用途使用,例如:
- 帮助开发人员为主管人员定义更好的类别。 在某些情况下,这种分类可能会有所帮助。 (例如,当您使用
aspect-oriented
,这些可能是pointcuts
的不错选择) -
@Repository
批注将为您的bean添加一些功能(一些自动异常转换到您的bean持久层)。 - 如果您使用的是Spring MVC,则只能将
@RequestMapping
添加到由@Controller
注释的类。
#11楼
在春季4,最新版本:
@Repository批注是实现存储库的角色或构造型(也称为数据访问对象或DAO)的任何类的标记。 如第20.2.2节“异常转换”中所述,此标记的用途是自动转换异常。
Spring提供了进一步的构造型注释:@ Component,@ Service和@Controller。 @Component是任何Spring托管组件的通用构造型。 @ Repository,@ Service和@Controller是@Component的特化,用于更具体的用例,例如分别在持久层,服务层和表示层中。 因此,您可以使用@Component来注释组件类,但是通过使用@ Repository,@ Service或@Controller来注释组件类,您的类更适合于通过工具进行处理或与方面相关联。 例如,这些构造型注释成为切入点的理想目标。 在Spring框架的未来版本中,@ Repository,@ Service和@Controller也可能带有其他语义。 因此,如果在服务层使用@Component或@Service之间进行选择,则@Service显然是更好的选择。 同样,如上所述,@ Repository已被支持作为持久层中自动异常转换的标记。
#12楼
由于许多答案已经说明了这些批注的用途,因此我们将重点关注它们之间的一些细微差异。
首先相似
值得再次强调的第一点是, 对于BeanDefinition的扫描自动检测和依赖性注入,所有这些注释(即@ Component,@ Service,@ Repository,@ Controller)都是相同的。 我们可以用一个代替另一个,并且仍然可以解决问题。
@ Component,@ Repository,@ Controller和@Service之间的区别
@零件
这是一个通用的构造型注释,指示该类是弹簧组件。
@Component有什么特别之处 <context:component-scan>
仅扫描@Component
,通常不查找@Controller
, @Service
@Controller
和@Repository
。 扫描它们是因为它们本身带有@Component
注释。
只需看看@Controller
, @Service
@Controller
和@Repository
注释定义:
@Component
public @interface Service {
….
}
@Component
public @interface Repository {
….
}
@Component
public @interface Controller {
…
}
因此,说@Controller
, @Service
@Controller
和@Repository
是@Component
注释的特殊类型是没有错的。 <context:component-scan>
拾取它们并将其以下类注册为bean,就像它们使用@Component
进行注释一样。
还扫描特殊类型的注释,因为它们本身使用@Component
注释进行注释,这意味着它们也是@Component
。 如果我们定义自己的自定义注释并使用@Component
对其进行注释,则还将使用<context:component-scan>
@资料库
这表示该类定义了一个数据存储库。
@Repository有什么特别之处?
除了指出这是基于Annotation的Configuration之外 , @Repository
的工作是捕获特定于平台的异常,并将它们作为Spring统一的未经检查的异常之一重新抛出。 为此,我们提供了PersistenceExceptionTranslationPostProcessor
,我们需要将其添加到Spring的应用程序上下文中,如下所示:
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
这个bean后处理器将顾问程序添加到任何使用@Repository
注释的bean,以便捕获任何特定于平台的异常,然后将它们重新抛出为Spring的未经检查的数据访问异常之一。
@Controller
@Controller
注释指示特定的类充当控制器的角色。 @Controller
注释充当带注释的类的@Controller
型,指示其作用。
@Controller有什么特别之处?
即使它们看起来相同,我们也无法将其与@Service
或@Repository
类的任何其他对象切换。 调度程序扫描用@Controller
注释的类,并在其中检测用@RequestMapping
注释注释的方法。 我们可以使用@RequestMapping
只有其类注释与方法上/ @Controller
,它不会与工作@Component
, @Service
, @Repository
等..
注意:如果一个类是通过任何替代方法通过已注册为一个bean,像@Bean
或通过@Component
, @Service
等...注释,然后@RequestMapping
如果类也与注释可挑@RequestMapping
注解。但这是另一种情况。
@服务
@Service
bean在存储库层中保存业务逻辑和调用方法。
@Service有什么特别之处?
除了它用来指示它保持业务逻辑这一事实外,此注释中没有其他可注意到的东西。 但是谁知道,Spring将来可能会增加一些额外的例外。
还有什么?
与上述类似,将来,Spring可能会基于它们的分层约定为@Service
@Controller
, @Repository
@Controller
和@Repository
添加特殊功能。 因此,尊重约定并与层配合使用始终是一个好主意。
#13楼
@Component
是顶级通用注释,它使被注释的Bean可以被扫描并在DI容器中可用
@Repository
是专门的注释,它具有转换DAO类中所有未检查的异常的功能
@Service
是专用注释。 到目前为止,它没有带来任何新功能,但是它阐明了Bean的意图。
@Controller是专门的注释,它使Bean MVC可以@RequestMapping
,并允许使用进一步的注释,例如@RequestMapping
和所有此类注释
这里有更多细节
#14楼
@Service
引用spring文档,
指示带注释的类是“服务”, 最初由Domain-Driven Design(Evans,2003)定义为“作为接口提供的操作,在模型中是独立的,没有封装状态”。 可能还表明某个类是“业务服务门面”(就核心J2EE模式而言)或类似的东西。 此注释是通用的刻板印象,各个团队可以缩小其语义并适当使用。
如果您看一下eric evans的域驱动设计,
SERVICE是作为接口提供的一种操作,在模型中是独立存在的,没有像ENTITIES和VALUE OBJECTS那样封装状态。 服务是技术框架中的常见模式,但它们也可以应用于领域层。 名称服务强调与其他对象的关系。 与ENTITIES和VALUE OBJECTS不同,它纯粹是根据对客户的作用来定义的。 SERVICE倾向于为活动而不是实体命名,是动词而不是名词。 服务仍然可以有一个抽象的,有意的定义; 它只是具有与对象定义不同的风格。 服务仍应具有已定义的责任,并且应将责任和履行该责任的接口定义为域模型的一部分。 操作名称应来自UBIQUITOUS语言或引入UBIQUITOUS语言。 参数和结果应该是域对象。 应谨慎使用服务,不得剥夺其所有行为的实体和值对象。 但是,当操作实际上是重要的领域概念时,SERVICE构成了模型驱动设计的自然组成部分。 在模型中声明为SERVICE,而不是实际上不代表任何东西的伪对象,独立操作不会误导任何人。
以及Eric Evans的Repository
,
存储库将某种类型的所有对象表示为概念集(通常是模拟的)。 除了具有更复杂的查询功能外,它的作用类似于集合。 添加和删除了适当类型的对象,并且REPOSITORY背后的机器将其插入或从数据库中删除。 该定义收集了一系列有凝聚力的职责,以提供从早期生命周期到末期访问AGGREGATES根源的权限。
#15楼
从技术上讲, @Service
, @Repository
@Controller
, @Service
@Repository
都是相同的。 它们都扩展了@Component
。
从Spring源代码:
指示带注释的类是“组件”。 当使用基于注释的配置和类路径扫描时,此类会被视为自动检测的候选。
我们可以为每个bean直接使用@Component
,但是为了更好地理解和维护大型应用程序,我们使用@Controller
@Service
, @Repository
@Controller
和@Repository
。
每个注释的目的:
-
@Controller
>带有注释的类旨在接收来自客户端的请求。 第一个请求到达Dispatcher Servlet,在此它使用@RequestMapping
批注的值将请求传递到特定的控制器。 -
@Service
>带有此注释的类旨在处理我们从客户端接收或从数据库获取的数据。 所有对数据的操作都应在此层中完成。 -
@Repository
>带有注释的类旨在与数据库连接。 也可以将其视为DAO(数据访问对象)层。 该层应仅限于CRUD(创建,检索,更新,删除)操作。 如果需要任何操作,则应将数据发送回@Service层。
如果我们交换它们的位置(使用@Repository
代替@Controller
),我们的应用程序将正常运行。
使用三种不同的@annotations
的主要目的是为Enterprise应用程序提供更好的模块化。
#16楼
@Component :注释一个类@Component,它告诉休眠它是一个Bean。
@Repository :注释一个类@Repository,它告诉休眠状态它是一个DAO类,并将其视为DAO类。 意味着它使未经检查的异常(从DAO方法抛出)可以转换为Spring DataAccessException。
@Service :这告诉hibernate这是一个Service类,在其中您将具有@Transactional等Service层注释,因此hibernate将其视为Service组件。
加@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");
#17楼
使用@Component注释其他组件,例如REST资源类。
@Component
public class AdressComp{
.......
...//some code here
}
@Component是任何Spring托管组件的通用构造型。
@ Controller,@ Service和@Repository是@Component针对特定用例的特化。
春天的@Component
#18楼
刻板印象的解释:
-
@Service
注释所有服务类。 该层知道工作单元。 您所有的业务逻辑都将在Service类中。 通常,事务层涵盖服务层的方法。 您可以从服务方法进行多个DAO调用,如果一个事务失败,则所有事务都应回滚。 -
@Repository
注释所有DAO类。 您所有的数据库访问逻辑都应在DAO类中。 -
@Component
Component-用组件@Component
注释其他组件(例如REST资源类)。 -
@Autowired
让Spring使用@Autowired注释将其他bean自动连接到您的类中。
@Component
是任何Spring托管组件的通用@Component
型。 @Repository
, @Service
@Controller
和@Controller
是@Component
用于更具体的用例,例如分别在持久层,服务层和表示层中。
原来在这里回答。
#19楼
@ Component,@ Repository,@ Service,@ Controller:
@Component是由Spring @Repository管理的组件的通用构造型,@Service和@Controller是@Component专长,用于更特定的用途:
- @用于持久性的存储库
- @服务和交易服务
- 用于MVC控制器的@Controller
为什么要在@Component上使用@ Repository,@ Service,@ Controller? 我们可以用@Component标记我们的组件类,但是如果相反,我们将使用适合预期功能的替代方法。 我们的类更适合每种情况下预期的功能。
带有“ @Repository”注释的类通过org.springframework.dao.DataAccessException具有更好的翻译和可读错误处理。 实现访问数据的组件(DataAccessObject或DAO)的理想选择。
带“ @Controller”的带注释的类在Spring Web MVC应用程序中扮演控制器的角色
带“ @Service”的带注释的类在业务逻辑服务中起作用,例如DAO管理器的Facade模式(Facade)和事务处理
#20楼
在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文件中添加<context:component-scan>
,spring将在上下文创建/加载阶段自动创建那些使用上述注释进行注释的类的对象。
#21楼
@component
@controller
@Repository
@service
@RestController
这些都是StereoType注释。这对于将类作为ioc容器中的spring bean有用,
#22楼
存储库和服务是组件注释的子级。 因此,它们都是Component 。 存储库和服务只是将其扩展。 到底如何 服务只有意识形态上的区别:我们将其用于服务。 存储库具有特定的异常处理程序。
#23楼
为了简化此说明,让我们按用例考虑技术性,这些注解用于注入,正如我所说的“ 用于注入 ”,也就是说,如果您知道如何使用依赖注入“ DI”,并且应该,那么您将始终寻找这些注释,并通过使用这些Stereo Types注释这些类,来通知DI容器对其进行扫描以准备在其他地方进行注入,这是实际的目标。
现在让我们移动到每个; 首先@Service ,如果您要为特定业务案例构建一些逻辑,则需要在包含业务逻辑的地方将其分开,此服务是普通Class,或者您可以将其用作接口,并且其编写方式如下:这个
@Service
public class Doer {
// Your logic
}
// To use it in another class, suppose in Controller
@Controller
public class XController {
// You have to inject it like this
@Autowired
private Doer doer;
}
注入它们时,所有方法都是相同的, @ Repository是一个接口,适用于Repository Pattern Repository设计模式的实现 ,通常在处理某些数据存储或数据库时使用,您会发现它包含多个为您处理数据库操作的现成实现; 它可以是CrudRepository , JpaRepository等。
// For example
public interface DoerRepository implements JpaRepository<Long, XEntity> {}
最后@Component ,这是Spring中已注册bean的通用形式,即Spring一直在寻找标记有@Component的bean进行注册,然后@Service和@Repository都是@Component的特例,但是是常见的用例组件是指您制作纯粹是技术性的东西而不是涵盖直接业务案例时! 例如格式化日期或处理特殊请求序列化机制等。
#24楼
这里有足够好的答案来解释组件存储库服务注释之间的区别。 我想分享@Controller & @RestController
之间的区别
@Controller
vs RestController
@RestController
:
- 此注释是
@Controller
的专用版本,它会自动添加@Controller
和@ResponseBody
注释。 因此我们不必将@ResponseBody
添加到我们的映射方法中。 这意味着@ResponseBody
默认为活动状态。 - 如果使用
@RestController
,则无法返回视图(通过在Spring / Spring-Boot中使用Viewresolver
) -
@RestController
还会自动将响应转换为JSON/XML automatically
因为@ResponseBody
将返回的对象制作为可能在正文中的对象,eg JSON or XML
@Controller
-
@Controller
用于将类标记为Spring MVC Controller。 此注释只是@Component
的专用版本,它允许基于类路径扫描自动检测控制器类。 -
@Controller
您可以在Spring Web MVC中返回视图。
#25楼
@ Component,@ Repository,@ Controller和@Service批注之间的区别
@Component –通用,可以在整个应用程序中使用。
@Service –在服务层级别注释类。
@Controller –在表示层级别注释类,主要在Spring MVC中使用。
@Repository –在持久层注释类,它将充当数据库存储库。
@Controller
= @Component(内部注释)+表示层功能 @Service
= @Component(内部注释)+服务层功能 @Component
=实际组件(Beans) @Repository
= @Component(内部注释)+数据层功能(用于处理域Bean)
#26楼
它们几乎相同-所有这些都意味着该类是Spring bean。 @Service
@Controller
, @Repository
和@Controller
是专用的@Component
。 您可以选择对它们执行特定的操作。 例如:
-
@Controller
bean由spring-mvc使用 -
@Repository
bean有资格进行持久性异常翻译
另一件事是您在语义上将组件指定给不同的层。
@Component
提供的一件事是,您可以用它注释其他注释,然后以与@Service
相同的方式使用它们。
例如最近我做了:
@Component
@Scope("prototype")
public @interface ScheduledJob {..}
因此,所有带有@ScheduledJob
注释的类都是spring bean,除此之外,它们都注册为石英作业。 您只需要提供处理特定注释的代码即可。
#27楼
从Spring文档 :
在Spring 2.0和更高版本中,
@Repository
批注是满足存储库角色或构造型(也称为数据访问对象或DAO)的任何类的标记。 该标记的用途包括自动翻译例外。Spring 2.5引入了更多的
@Component
型注释:@Component
,@Service
@Controller
和@Controller
。@Component
是任何Spring托管组件的通用@Component
型。@Repository
,@Service
@Controller
和@Controller
是@Component
用于更具体的用例,例如分别在持久层,服务层和表示层中。因此,您可以使用
@Component
来注释组件类,但是可以使用@Repository
,@Service
@Controller
或@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) │
└────────────┴─────────────────────────────────────────────────────┘