@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?
换句话说,如果我有一个Service类,并且我将注释从@Service更改为@Component,它的行为是否仍然相同?
或者注释是否也会影响类的行为和功能?
@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?
换句话说,如果我有一个Service类,并且我将注释从@Service更改为@Component,它的行为是否仍然相同?
或者注释是否也会影响类的行为和功能?
当前回答
由于许多答案已经说明了这些注释的用途,我们将在这里重点讨论它们之间的一些细微差异。
首先是相似性值得再次强调的第一点是,关于扫描自动检测和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添加特殊功能。因此,尊重惯例并按照层使用它总是一个好主意。
其他回答
它们几乎相同——所有这些都意味着这个类是一个Spring bean@Service、@Repository和@Controller是专门的@Components。您可以选择与他们一起执行特定操作。例如:
@springmvc使用控制器bean@存储库bean有资格进行持久性异常转换
另一件事是将组件语义上指定给不同的层。
@Component提供的一点是,您可以用它注释其他注释,然后以与@Service相同的方式使用它们。
例如,最近我做了:
@Component
@Scope("prototype")
public @interface ScheduledJob {..}
因此,所有用@ScheduledJob注释的类都是springbean,除此之外,它们还注册为石英作业。您只需要提供处理特定注释的代码。
来自Spring文档:
@Repository注释是满足存储库的角色或原型(也称为数据访问对象或DAO)。该标记的用途之一是自动翻译异常,如异常转换中所述。Spring提供了更多的原型注释:@Component、@Service、,和@Controller@组件是任何Spring管理的组件@Repository、@Service和@Controller是@Component的专门化,用于更具体的用例(在持久性、服务和表示层)。因此,您可以使用@component注释组件类,但是,通过用@Repository、@Service或@Controller注释它们相反,您的类更适合由工具处理或与方面相关。例如,这些原型注释成为切入点的理想目标@存储库、@Service和@控制器还可以在未来版本的Spring框架。因此,如果您在使用@组件或服务层的@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) |
@Component、@Repository、@Controller和@Service注释之间的差异
@组件–通用,可跨应用程序使用@服务–在服务层级别注释类@控制器–注释表示层级别的类,主要用于SpringMVC。@Repository–在持久层注释类,它将充当数据库存储库。
@控制器=@Component(内部注释)+表示层功能@服务=@Component(内部注释)+服务层功能@分量=实际分量(豆类)@Repository=@Component(内部注释)+数据层特性(用于处理域bean)
从数据库连接的角度来看,使用@Service和@Repository注释很重要。
对所有web服务类型的DB连接使用@Service将@Repository用于所有存储过程数据库连接
如果没有使用正确的注释,则可能会遇到回滚事务覆盖的提交异常。您将在压力负载测试期间看到与回滚JDBC事务相关的异常。
Spring支持多种类型的注释,如@Component、@service、@Repository。所有这些都可以在org.springframework.stereotype包下找到,@Bean可以在org.spring framework.context.annotation包下找到。
当我们的应用程序中的类使用上述任何注释进行注释时,在项目启动期间,对每个类进行春季扫描(使用@ComponentScan),并将类的实例注入IOC容器。@ComponentScan要做的另一件事是运行带有@Bean的方法,并将返回对象作为Bean还原到Ioc容器。
在深入研究(@Component vs@service vs@Repository)之前,最好先了解@Bean和@Component之间的区别
@组件vs@存储库vs@服务
在大多数典型的应用程序中,我们有不同的层,如数据访问、表示、服务、业务等。此外,在每个层中,我们都有不同的bean。为了自动检测这些bean,Spring使用类路径扫描注释。然后在ApplicationContext中注册每个bean。
以下是其中一些注释的简短概述:
@组件是任何Spring管理组件的通用原型。@服务在服务层注释类。@Repository在持久层对类进行注释,持久层将充当数据库存储库。
@零部件注释
@Component是一个类级别的注释。我们可以在应用程序中使用@Component将bean标记为Spring的托管组件。Spring只会使用@Component获取和注册bean,通常不会查找@Service和@Repository。
它们在ApplicationContext中注册,因为它们用@Component注释
如前所述,@Component是所有原型注释的父级。当Spring执行组件扫描时,它只查找标记有@component注释的类。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
我们可以在所有类上使用这个注释,它不会造成任何差异。
@服务注释
我们用@Service标记bean,以表示它们持有业务逻辑。除了在服务层中使用之外,该注释没有任何其他特殊用途。
@Service是组件的子级,用于表示应用程序服务层的类。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
@存储库批注
@Repository的任务是捕获特定于持久性的异常,并将其作为Spring的统一未检查异常之一重新抛出。
为此,Spring提供了PersistenceExceptionTranslationPostProcessor,我们需要将其添加到应用程序上下文中(如果我们使用的是Spring Boot,则已经包括在内):
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
这个bean后处理器向用@Repository注释的任何bean添加一个advisor。
类似地,@Repository也是组件注释的子级,用于属于持久性数据访问层并用作数据存储库的类。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
总结
@Service和@Repository是@Component的特例。它们在技术上是相同的,但我们使用它们的目的不同。根据它们的层约定选择注释总是一个好主意。