@Component、@Repository和@Service注释是否可以在Spring中互换使用,或者它们除了充当符号设备之外,是否提供任何特定功能?

换句话说,如果我有一个Service类,并且我将注释从@Service更改为@Component,它的行为是否仍然相同?

或者注释是否也会影响类的行为和功能?


当前回答

@Component:你注释一个类@Component,它告诉hibernate它是一个Bean。

@Repository:您注释一个类@Repositories,它会告诉hibernate它是一个DAO类,并将其视为DAO类。意味着它使未检查的异常(从DAO方法抛出)有资格转换为SpringDataAccessException。

@服务:这告诉hibernate它是一个服务类,您将在其中使用@Transactional等服务层注释,因此hibernate将其视为服务组件。

另外,@Service是@Component的进步。假设bean类名为CustomerService,因为您没有选择XMLbean配置方式,所以您使用@Component注释了bean,以将其指示为bean。因此,在获取bean对象CustomerService cust=(CustomerService)context.getBean(“CustomerService”)时;默认情况下,Spring会将组件的第一个字符从“CustomerService”小写为“CustomerService”。您可以检索名为“customerService”的组件。但是,如果对bean类使用@Service注释,则可以通过以下方式提供特定的bean名称

@Service("AAA")
public class CustomerService{

您可以通过

CustomerService cust = (CustomerService)context.getBean("AAA");

其他回答

在Spring@Component中,@Service、@Controller和@Repository是Stereotype注释,用于:

@Controller:在完成了来自演示页面的请求映射的地方,即演示层不会转到任何其他文件,它会直接转到@Controller类,并在@RequestMapping注释中检查请求的路径,如果需要,该注释在方法调用之前编写。

@服务:所有业务逻辑都在这里,即与数据相关的计算和所有。此业务层注释中,我们的用户不直接调用持久性方法,因此将使用此注释调用此方法。它将根据用户请求请求@Repository

@存储库:这是用于从数据库获取数据的应用程序的持久层(数据访问层)。即,所有与数据库相关的操作都由存储库完成。

@组件-使用组件原型注释其他组件(例如REST资源类)。

指示带注释的类是“组件”。此类类为使用时被视为自动检测的候选项基于注释的配置和类路径扫描。其他类级别注释可被视为标识组件,通常是一种特殊类型的组件:例如@Repository注解或AspectJ的@Aspect注解。

@Component:你注释一个类@Component,它告诉hibernate它是一个Bean。

@Repository:您注释一个类@Repositories,它会告诉hibernate它是一个DAO类,并将其视为DAO类。意味着它使未检查的异常(从DAO方法抛出)有资格转换为SpringDataAccessException。

@服务:这告诉hibernate它是一个服务类,您将在其中使用@Transactional等服务层注释,因此hibernate将其视为服务组件。

另外,@Service是@Component的进步。假设bean类名为CustomerService,因为您没有选择XMLbean配置方式,所以您使用@Component注释了bean,以将其指示为bean。因此,在获取bean对象CustomerService cust=(CustomerService)context.getBean(“CustomerService”)时;默认情况下,Spring会将组件的第一个字符从“CustomerService”小写为“CustomerService”。您可以检索名为“customerService”的组件。但是,如果对bean类使用@Service注释,则可以通过以下方式提供特定的bean名称

@Service("AAA")
public class CustomerService{

您可以通过

CustomerService cust = (CustomerService)context.getBean("AAA");

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的特例。它们在技术上是相同的,但我们使用它们的目的不同。根据它们的层约定选择注释总是一个好主意。

In-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.

上面声明的注释是特殊的,因为当我们将<context:componentscan>添加到xxx-servlet.xml文件中时,spring将自动创建那些在上下文创建/加载阶段用上面的注释注释的类的对象。

为了简化这一说明,让我们通过用例来考虑技术性,这些注释用于注入,正如我所说的“用于注入”,这意味着,如果你知道如何使用依赖注入“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的特例,然而,组件的常见用例是当您制作一些纯技术性的东西而不是直接的业务案例时!比如格式化日期或处理特殊的请求序列化机制等等。