What's the difference between @Component, @Repository & @Service annotations in Spring?
CAN
在其他的话,如果我有一个服务类的变化从第一到
或做注释的行为也影响和功能的类?
从Spring文档:
In Spring 2.0 and later, the
@Repository annotation is a marker for
any class that fulfills the role or stereotype (also known as Data
Access Object or DAO) of a repository. Among the uses of this marker
is the automatic translation of exceptions.Spring 2.5 introduces further stereotype annotations:
@Component ,
@Service , and@Controller .@Component is a generic stereotype for any
Spring-managed component.@Repository ,@Service , and@Controller are
specializations of@Component for more specific use cases, for
example, in the persistence, service, and presentation layers,
respectively.Therefore, you can annotate your component classes with
@Component ,
but by annotating them with@Repository ,@Service , or@Controller
instead, your classes are more properly suited for processing by tools
or associating with aspects. For example, these stereotype annotations
make ideal targets for pointcuts.Thus, if you are choosing between using
@Component or@Service for
your service layer,@Service is clearly the better choice. Similarly,
as stated above,@Repository is already supported as a marker for
automatic exception translation in your persistence layer.
1 2 3 4 5 6 7 8 | ┌────────────┬─────────────────────────────────────────────────────┐ │ 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) │ └────────────┴─────────────────────────────────────────────────────┘ |
由于许多答案已经说明了这些注释的用途,我们将在这里重点讨论它们之间的一些细微差异。
First the Similarity
First point worth highlighting again is that with respect to scan-auto-detection and dependency injection for BeanDefinition all these annotations (viz., @Component, @Service,
@Repository, @Controller) are the same. We can use one in place
of another and can still get our way around.
@component、@repository、@controller和@service之间的差异
@Component
这是一个通用的原型注释,指示类是一个Spring组件。
@component有什么特别之处
看看
1 2 3 4 |
nbsp;
1 2 3 4 |
nbsp;
1 2 3 4 |
因此,可以说
特殊类型注释也会被扫描,因为它们本身是用
@Repository
这表示类定义了一个数据存储库。
@repository有什么特别之处?
除了指出这是一种基于注释的配置之外,
1 | <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> |
这个bean后处理程序向用
@Controller
@controller有什么特别之处?
我们不能将此注释与任何其他类似于
@Service
@service有什么特别之处?
除了它用来表示,它持有业务逻辑之外,在这个注释中没有其他值得注意的东西;但是谁知道呢,Spring将来可能会添加一些额外的异常。
What else?
与上述类似,在未来的春天,可以根据分层约定为
它们几乎是相同的-所有这些都意味着这个班是一个菜豆。
- 弹簧MVC使用
@Controller 豆 @Repository bean可以进行持久性异常转换。
另一件事是您将组件语义地指定给不同的层。
例如,最近我做了:
1 2 3 |
因此,所有用
@分量等于
1 | <bean> |
@服务,@controller,@repository=@component+一些更特殊的功能
这意味着服务、控制器和存储库在功能上是相同的。
这三个注释用于分隔应用程序中的"层"。
- 控制器只是做一些诸如调度、转发、呼叫服务方法等的事情。
- 服务保留业务逻辑、计算等。
- 存储库是DAOS(数据访问对象),它们直接访问数据库。
现在您可能会问为什么要将它们分开:(我假设您了解面向方面的AOP编程)
假设您只想监视DAO层的活动。您将编写一个方面(类)类,在调用DAO的每个方法之前和之后进行一些日志记录,因为您有三个不同的层,并且不混合。
因此,您可以对DAO方法执行"around"、"before"或"after"的日志记录。你可以这样做,因为你首先有一把刀。你刚刚实现的是关注点或任务的分离。
想象一下,如果只有一个annotation@controller,那么这个组件的调度、业务逻辑和访问数据库都是混合的,所以代码太脏了!
上面提到的是一个非常常见的场景,有更多的用例说明为什么要使用三个注释。
在春季,
Indicates that an annotated class is a"component". Such classes are
considered as candidates for auto-detection when using
annotation-based configuration and classpath scanning.Other class-level annotations may be considered as identifying a
component as well, typically a special kind of component: e.g. the
@Repository annotation or AspectJ's @Aspect annotation.
Spring 2.5 introduces further stereotype annotations: @Component, @Service and @Controller. @Component serves as a generic stereotype for any Spring-managed component; whereas, @Repository, @Service, and @Controller serve as specializations of @Component for more specific use cases (e.g., in the persistence, service, and presentation layers, respectively). What this means is that you can annotate your component classes with @Component, but by annotating them with @Repository, @Service, or @Controller instead, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets for pointcuts. Of course, it is also possible that @Repository, @Service, and @Controller may carry additional semantics in future releases of the Spring Framework. Thus, if you are making a decision between using @Component or @Service for your service layer, @Service is clearly the better choice. Similarly, as stated above, @Repository is already supported as a marker for automatic exception translation in your persistence layer.
1
2
3
4 @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编写配置
从数据库连接的角度来看,使用
如果不使用正确的注释,则可能会面临由回滚事务重写的提交异常。您将在压力负载测试期间看到与回滚JDBC事务相关的异常。
@存储库@service和@controller用作@component的专门化,以便更具体地使用。在此基础上,您可以将@service替换为@component,但在这种情况下,您将失去专门化。
1 2 | 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. |
技术上,@controller,@service,@repository都是相同的。它们都扩展了@components。
从Spring源代码:
指示带批注的类是"组件"。当使用基于注释的配置和类路径扫描时,这些类被认为是自动检测的候选者。
我们可以直接为每个bean使用@component,但是为了更好地理解和维护大型应用程序,我们使用@controller、@service、@repository。
每个注释的目的:
1)@controller->classes用此注释,用于接收客户端的请求。第一个请求到达Dispatcher servlet,在那里它使用@requestmapping annotation的值将请求传递给特定的控制器。
2)@service->classes用这个注释,目的是操作我们从客户机接收或从数据库获取的数据。所有使用数据的操作都应该在这个层中完成。
3)@repository->classes加上注释后,用于连接数据库。它也可以被视为DAO(数据访问对象)层。此层应仅限于CRUD(创建、检索、更新、删除)操作。如果需要任何操作,则应将数据发送回@service layer。
如果我们交换它们的位置(使用@repository代替@controller),我们的应用程序将正常工作。
使用三个不同的@annotations的主要目的是为企业应用程序提供更好的模块化。
所有这些注释都是立体声类型的注释,这三个注释之间的区别是
- If we add the @Component then it tells the role of class is a component class it means it is a class consisting some logic,but it
does not tell whether a class containing a specifically business or
persistence or controller logic so we don't use directly this
@Component annotation- If we add @Service annotation then it tells that a role of class consisting business logic
- If we add @Repository on top of class then it tells that a class consisting persistence logic
- Here @Component is a base annotation for @Service,@Repository and @Controller annotations
例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 注释将在类的顶部存在。
Spring提供了四种不同类型的自动组件扫描注释,分别是
在注释类的同时,应该选择更专业的
用@component注释其他组件,例如REST资源类。
1 2 3 4 5 |
@组件是任何Spring管理的组件的通用原型。
@控制器、@service和@repository是@component针对特定用例的专门化。
@弹簧组件我们可以按照Java标准来回答这个问题。
参照现在由Spring支持的
但是Spring用户这些不同的注释对于特定用途是不同的,例如:
春季4日,最新版本:
The @Repository annotation is a marker for any class that fulfills the
role or stereotype of a repository (also known as Data Access Object
or DAO). Among the uses of this marker is the automatic translation of
exceptions as described in Section 20.2.2,"Exception translation".Spring provides further stereotype annotations: @Component, @Service,
and @Controller. @Component is a generic stereotype for any
Spring-managed component. @Repository, @Service, and @Controller are
specializations of @Component for more specific use cases, for
example, in the persistence, service, and presentation layers,
respectively. Therefore, you can annotate your component classes with
@Component, but by annotating them with @Repository, @Service, or
@Controller instead, your classes are more properly suited for
processing by tools or associating with aspects. For example, these
stereotype annotations make ideal targets for pointcuts. It is also
possible that @Repository, @Service, and @Controller may carry
additional semantics in future releases of the Spring Framework. Thus,
if you are choosing between using @Component or @Service for your
service layer, @Service is clearly the better choice. Similarly, as
stated above, @Repository is already supported as a marker for
automatic exception translation in your persistence layer.
即使我们交换@component、@repository或@service
它的行为是相同的,但有一个方面是,如果我们使用组件或@service,它们将无法捕获与DAO而不是存储库相关的特定异常。
@component、@service、@controller、@repository之间没有区别。@组件是表示MVC组件的通用注释。但作为我们MVC应用程序的一部分,将有几个组件,如服务层组件、持久层组件和表示层组件。所以为了区分它们,春天的人们也给出了另外三个注解。
表示持久层组件:@repository
表示服务层组件:@service
表示表示表示层组件:@controller
或者,您可以对所有组件使用@component。
@控制器是专门的注释,它使bean mvc意识到并允许使用进一步的注释,如
以下是详细信息
一份
Indicates that an annotated class is a"Service", originally defined
by Domain-Driven Design (Evans, 2003) as"an operation offered as an
interface that stands alone in the model, with no encapsulated state."
May also indicate that a class is a"Business Service Facade" (in the
Core J2EE patterns sense), or something similar. This annotation is a
general-purpose stereotype and individual teams may narrow their
semantics and use as appropriate.
如果你看看埃里克·埃文斯的领域驱动设计,
A SERVICE is an operation offered as an interface that stands alone in
the model, without encapsulating state, as ENTITIES and VALUE OBJECTS
do. SERVICES are a common pattern in technical frameworks, but they
can also apply in the domain layer. The name service emphasizes the
relationship with other objects. Unlike ENTITIES and VALUE OBJECTS, it
is defined purely in terms of what it can do for a client. A SERVICE
tends to be named for an activity, rather than an entity—a verb rather
than a noun. A SERVICE can still have an abstract, intentional
definition; it just has a different flavor than the definition of an
object. A SERVICE should still have a defined responsibility, and that
responsibility and the interface fulfilling it should be defined as
part of the domain model. Operation names should come from the
UBIQUITOUS LANGUAGE or be introduced into it. Parameters and results
should be domain objects. SERVICES should be used judiciously and not
allowed to strip the ENTITIES and VALUE OBJECTS of all their behavior.
But when an operation is actually an important domain concept, a
SERVICE forms a natural part of a MODEL-DRIVEN DESIGN. Declared in the
model as a SERVICE, rather than as a phony object that doesn't
actually represent anything, the standalone operation will not mislead
anyone.
根据埃里克·埃文斯的说法,还有一个
A REPOSITORY represents all objects of a certain type as a conceptual
set (usually emulated). It acts like a collection, except with more
elaborate querying capability. Objects of the appropriate type are
added and removed, and the machinery behind the REPOSITORY inserts
them or deletes them from the database. This definition gathers a
cohesive set of responsibilities for providing access to the roots of
AGGREGATES from early life cycle through the end.
@组件:注释一个class@component,它告诉Hibernate它是一个bean。
@存储库:您注释一个类@repository,它告诉Hibernate它是一个DAO类,并将其视为DAO类。意味着它使未检查的异常(从DAO方法抛出)有资格转换为SpringDataAccessException。
@服务:这告诉Hibernate它是一个服务类,您将在其中具有@Transactional ETC服务层注释,因此Hibernate将其视为服务组件。
加上@service是@component的高级。假设bean类名为customerservice,因为您没有选择XML bean配置方式,所以用@component注释bean以将其指示为bean。因此,在默认情况下获取bean对象
1 2 | @Service("AAA") public class CustomerService{ |
你可以通过
1 | CustomerService cust = (CustomerService)context.getBean("AAA"); |
存储库和服务是组件注释的子项。所以,它们都是组成部分。存储库和服务只是扩展它。究竟如何?服务只有意识形态上的区别:我们用它来服务。存储库具有特定的异常处理程序。
刻板印象的解释:
@Service —用@service注释所有服务类。这个层知道工作单元。您的所有业务逻辑都将在服务类中。一般来说,服务层的方法都包含在事务中。您可以从服务方法进行多个DAO调用,如果一个事务失败,则所有事务都应回滚。@Repository —用@repository注释所有DAO类。所有数据库访问逻辑都应该在DAO类中。@Component —用组件原型注释其他组件(例如REST资源类)。@Autowired -让Spring使用@autowired annotation自动将其他bean连接到类中。
最初在这里回答。
@组件,@repository,@service,@controller:
@组件是由spring@repository、@service和@controller管理的组件的通用构造型,它们是@component专门用于更具体的用途:
- @持久性存储库
- @服务和交易服务
- @MVC控制器控制器
为什么要在@component上使用@repository、@service、@controller?我们可以用@component标记我们的组件类,但是如果我们使用的是适应预期功能的替代方法。我们的类更适合于每种特定情况下预期的功能。
用"@repository"注释的类具有更好的翻译和可读的错误处理能力,可以使用org.springframework.dao.dataaccessexception。非常适合实现访问数据的组件(DataAccessObject或DAO)。
带有"@controller"的注释类在SpringWebMVC应用程序中扮演控制器角色。
带有"@service"的注释类在业务逻辑服务中扮演着角色,例如DAO管理器(facade)的facade模式和事务处理。
在Spring框架中,提供了一些特殊类型的注释,称为构造型注释。如下所示:
1 2 3 4 5 | @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. |
上面声明的注释是特殊的,因为当我们将
1 2 3 4 5 |
这些都是刻板的注释。这对于将类作为IOC容器中的SpringBeans来制作很有用,