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

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

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


当前回答

我们可以根据java标准回答这个问题

参考JSR-330,它现在被spring支持,您只能使用@Named来定义bean(不知何故,@Named=@Component)。因此,根据这个标准,似乎没有必要为类别bean定义原型(如@Repository、@Service、@Controller)。

但是spring用户在这些不同的注释中有不同的特定用途,例如:

帮助开发人员为胜任者定义更好的类别。这种分类在某些情况下可能会有所帮助。(例如,当您使用面向方面的时,这些可能是切入点的好候选)@存储库注释将为bean添加一些功能(为bean持久层添加一些自动异常转换)。如果您使用的是springMVC,则@RequestMapping只能添加到由@Controller注释的类中。

其他回答

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

它们几乎相同——所有这些都意味着这个类是一个Spring bean@Service、@Repository和@Controller是专门的@Components。您可以选择与他们一起执行特定操作。例如:

@springmvc使用控制器bean@存储库bean有资格进行持久性异常转换

另一件事是将组件语义上指定给不同的层。

@Component提供的一点是,您可以用它注释其他注释,然后以与@Service相同的方式使用它们。

例如,最近我做了:

@Component
@Scope("prototype")
public @interface ScheduledJob {..}

因此,所有用@ScheduledJob注释的类都是springbean,除此之外,它们还注册为石英作业。您只需要提供处理特定注释的代码。

@组件等效于

<bean>

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

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

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

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

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

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

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

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

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

@组件是顶级通用注释,它使带注释的bean能够被扫描并在DI容器中可用

@Repository是专门的注释,它具有转换DAO类中所有未检查的异常的功能

@服务是专门的注释。到目前为止,它没有带来任何新特性,但它阐明了bean的意图

@控制器是专门的注释,它使bean MVC意识到,并允许使用进一步的注释,如@RequestMapping等

以下是更多详细信息

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

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

从Spring源代码:

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

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

每个注释的目的:

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

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

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