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

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

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


当前回答

@存储库@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.

其他回答

@组件、@Repository、@Service、@Controller:

@Component是由Spring@Repository、@Service和@Controller管理的组件的通用原型,是用于更具体用途的@Component专用化:

@持久性存储库@服务和交易服务@MVC控制器的控制器

为什么在@Component上使用@Repository、@Service、@Controller?我们可以用@component标记我们的组件类,但如果相反,我们使用适应预期功能的替代方法。我们的类更适合每种特定情况下的预期功能。

用@Repository注释的类使用org.springframework.dao.DataAccessException具有更好的翻译和可读错误处理。非常适合实现访问数据的组件(DataAccessObject或dao)。

带有@Controller的注释类在SpringWebMVC应用程序中扮演控制器角色

带有@Service的注释类在业务逻辑服务中发挥作用,例如DAO Manager(Facade)的Facade模式和事务处理

在Spring 4中,最新版本:

@Repository注释是满足存储库的角色或原型(也称为数据访问对象或DAO)。该标记的用途之一是自动翻译第20.2.2节“例外翻译”中所述的例外。Spring提供了更多的原型注释:@Component、@Service、,和@Controller@组件是任何Spring管理的组件@Repository、@Service和@Controller是@Component的专门化,用于更具体的用例例如,在持久性、服务和表示层中,分别地因此,可以使用@组件,但使用@Repository、@Service或@相反,您的类更适合通过工具处理或与方面相关。例如,这些原型注释是切入点的理想目标。它也是@Repository、@Service和@Controller可能携带Spring框架未来版本中的附加语义。因此如果您选择使用@Component或@Service服务层,@service显然是更好的选择。同样,作为如上所述,@Repository已被支持作为持久化层中的自动异常转换。

@组件等效于

<bean>

@服务,@Controller,@Repository={@Component+一些更特殊的功能}

这意味着服务、控制器和存储库在功能上是相同的。

这三个注释用于分离应用程序中的“层”,

控制器只是做一些事情,比如调度、转发、调用服务方法等。服务保留业务逻辑、计算等。存储库是DAO(数据访问对象),它们直接访问数据库。

现在您可能会问为什么要将它们分开:(我假设您知道AOP面向方面编程)

假设您只想监视DAO层的活动。您将编写一个Aspect(A类)类,该类在调用DAO的每个方法之前和之后进行一些日志记录,您可以使用AOP来实现这一点,因为您有三个不同的层,并且没有混合。

因此,您可以在DAO方法的“周围”、“之前”或“之后”记录DAO。你可以这样做,因为你一开始就有一个DAO。您刚刚实现的是关注点或任务的分离。

想象一下,如果只有一个注解@Controller,那么这个组件的调度、业务逻辑和访问数据库都会混合在一起,代码太脏了!

上面提到的是一个非常常见的场景,还有很多使用三个注释的用例。

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

这些是Stereotype注释,可用于自动扫描

从技术上讲,@Controller、@Service、@Repository都是相同的。它们都扩展了@Component。

从Spring源代码:

指示带注释的类是“组件”。当使用基于注释的配置和类路径扫描时,此类类被视为自动检测的候选类。

我们可以对每个bean直接使用@Component,但为了更好地理解和维护大型应用程序,我们使用@Controller、@Service、@Repository。

每个注释的目的:

@带有此注释的Controller->类旨在接收来自客户端的请求。第一个请求来自DispatcherServlet,它使用@RequestMapping注释的值将请求传递给特定的控制器。@带有此注释的服务->类旨在处理我们从客户端接收或从数据库获取的数据。所有的数据操作都应该在这个层中完成。@存储库->带有此注释的类用于连接数据库。它也可以被认为是DAO(数据访问对象)层。该层应仅限于CRUD(创建、检索、更新、删除)操作。如果需要任何操作,数据应发送回@Service层。

如果我们交换它们的位置(使用@Repository代替@Controller),我们的应用程序将正常工作。

使用三种不同的@注释的主要目的是为Enterprise应用程序提供更好的模块性。