@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?
换句话说,如果我有一个Service类,并且我将注释从@Service更改为@Component,它的行为是否仍然相同?
或者注释是否也会影响类的行为和功能?
@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?
换句话说,如果我有一个Service类,并且我将注释从@Service更改为@Component,它的行为是否仍然相同?
或者注释是否也会影响类的行为和功能?
当前回答
它们几乎相同——所有这些都意味着这个类是一个Spring bean@Service、@Repository和@Controller是专门的@Components。您可以选择与他们一起执行特定操作。例如:
@springmvc使用控制器bean@存储库bean有资格进行持久性异常转换
另一件事是将组件语义上指定给不同的层。
@Component提供的一点是,您可以用它注释其他注释,然后以与@Service相同的方式使用它们。
例如,最近我做了:
@Component
@Scope("prototype")
public @interface ScheduledJob {..}
因此,所有用@ScheduledJob注释的类都是springbean,除此之外,它们还注册为石英作业。您只需要提供处理特定注释的代码。
其他回答
@Component、@Service、@Controller、@Repository之间没有区别。@Component是表示MVC组件的泛型注释。但作为MVC应用程序的一部分,将有几个组件,如服务层组件、持久层组件和表示层组件。所以为了区分它们,Spring的人也给出了其他三个注释。
表示持久层组件:@Repository表示服务层组件:@service表示表示层组件:@Controller否则,您可以对所有组件使用@Component。
为了简化这一说明,让我们通过用例来考虑技术性,这些注释用于注入,正如我所说的“用于注入”,这意味着,如果你知道如何使用依赖注入“DI”,并且你应该这样做,那么你将一直寻找这些注释,并通过使用这些立体类型来注释类,您正在通知DI容器扫描它们,以准备在其他地方进行注入,这是实际的目标。
现在让我们来看看每一个;first@Service,如果您正在为特定的业务案例构建一些逻辑,则需要在包含您的业务逻辑的地方将其分离,该服务是普通的Class,或者您可以根据需要将其用作接口,其编写方式如下
@Service
public class Doer {
// Your logic
}
要在另一个类中使用它,请假设在Controller中
@Controller
public class XController {
// You have to inject it like this
@Autowired
private Doer doer;
// Your logic
}
当你注入它们时,它们都是相同的方式,@Repository这是一个应用Repository Pattern Repository设计模式实现的接口,通常在处理某些数据存储或数据库时使用,你会发现,它包含多个现成的实现,供你处理数据库操作;它可以是CrudRepository、JpaRepository等。
例如:
public interface DoerRepository implements JpaRepository<Long, XEntity> {
}
最后,@Component,这是Spring中注册bean的通用形式,也就是说,Spring总是在寻找标记有@Component的bean来注册,那么@Service和@Repository都是@Component的特例,然而,组件的常见用例是当您制作一些纯技术性的东西而不是直接的业务案例时!比如格式化日期或处理特殊的请求序列化机制等等。
@组件等效于
<bean>
@服务,@Controller,@Repository={@Component+一些更特殊的功能}
这意味着服务、控制器和存储库在功能上是相同的。
这三个注释用于分离应用程序中的“层”,
控制器只是做一些事情,比如调度、转发、调用服务方法等。服务保留业务逻辑、计算等。存储库是DAO(数据访问对象),它们直接访问数据库。
现在您可能会问为什么要将它们分开:(我假设您知道AOP面向方面编程)
假设您只想监视DAO层的活动。您将编写一个Aspect(A类)类,该类在调用DAO的每个方法之前和之后进行一些日志记录,您可以使用AOP来实现这一点,因为您有三个不同的层,并且没有混合。
因此,您可以在DAO方法的“周围”、“之前”或“之后”记录DAO。你可以这样做,因为你一开始就有一个DAO。您刚刚实现的是关注点或任务的分离。
想象一下,如果只有一个注解@Controller,那么这个组件的调度、业务逻辑和访问数据库都会混合在一起,代码太脏了!
上面提到的是一个非常常见的场景,还有很多使用三个注释的用例。
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的特例。它们在技术上是相同的,但我们使用它们的目的不同。根据它们的层约定选择注释总是一个好主意。
刻板印象的解释:
@服务-使用@Service注释所有服务类。这一层知道工作单位。所有业务逻辑都将在服务类中。服务层的方法通常包含在事务中。您可以从服务方法进行多个DAO调用,如果一个事务失败,所有事务都应该回滚。@Repository-使用@Repository注释所有DAO类。所有数据库访问逻辑都应该在DAO类中。@组件-使用组件原型注释其他组件(例如REST资源类)。@Autowired-让Spring使用@Autowired注释自动将其他bean连接到类中。
@组件是任何Spring管理组件的通用原型@Repository、@Service和@Controller是@Component的专门化,用于更具体的用例,例如,分别在持久性、服务和表示层中。
最初在这里回答。