@Repository
@Component
, @Repository
和@Service
注释可以在 Spring 中互换使用,还是除了作为符号设备之外还提供任何特定的功能?
换句话说,如果我有一个 Service 类并且我将注释从@Service
更改为@Component
,它仍然会以相同的方式运行吗?
或者注释是否也会影响类的行为和功能?
从Spring 文档 :
在 Spring 2.0 及更高版本中,
@Repository
注释是任何满足存储库的角色或构造型(也称为数据访问对象或 DAO)的类的标记。该标记的用途之一是异常的自动转换。Spring 2.5 引入了更多的
@Component
型注释:@Component
,@Service
@Controller
和@Controller
。@Component
是任何 Spring 管理组件的通用@Component
型。@Repository
,@Service
@Controller
和@Controller
是@Component
用于更具体的用例,例如,分别在持久性,服务和表示层中。因此,您可以使用
@Component
注释组件类,但是通过使用@Repository
,@Service
@Controller
或@Controller
注释它们,您的类更适合通过工具处理或与方面关联。例如,这些刻板印象注释成为切入点的理想目标。因此,如果您选择在服务层使用
@Component
或@Service
Service,@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) │
└────────────┴─────────────────────────────────────────────────────┘
由于许多答案已经说明了这些注释的用途,我们将在这里集中讨论它们之间的一些细微差别。
首先是相似性
值得再次强调的第一点是, 对于 BeanDefinition 的扫描自动检测和依赖注入,所有这些注释(即 @ Component,@ Service,@ Repository,@ Controller)都是相同的。 我们可以使用一个代替另一个,仍然可以解决问题。
@零件
这是一个通用的构造型注释,表明该类是一个 spring 组件。
@Component 有什么特别之处
<context:component-scan>
仅扫描@Component
,并且一般不会查找@Controller
, @Service
@Controller
和@Repository
。扫描它们是因为它们本身都是用@Component
注释的。
只需看看@Controller
, @Service
@Controller
和@Repository
注释定义:
@Component
public @interface Service {
….
}
@Component
public @interface Repository {
….
}
@Component
public @interface Controller {
…
}
因此,说@Controller
, @Service
@Controller
和@Repository
是特殊类型的@Component
注释并没有错。 <context:component-scan>
选择它们并将它们的后续类注册为 bean,就好像它们是用@Component
注释一样。
扫描它们是因为它们本身都使用@Component
注释进行注释。如果我们定义自己的自定义注释并使用@Component
注释它,那么它也将使用<context:component-scan>
@Repository
这是为了表明该类定义了一个数据存储库。
@Repository 有什么特别之处?
除了指出这是一个基于注释的配置之外 , @Repository
的工作是捕获平台特定的异常并将它们重新抛出为 Spring 的统一未经检查的异常之一。为此,我们提供了PersistenceExceptionTranslationPostProcessor
,我们需要在 Spring 的应用程序上下文中添加如下:
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
这个 bean 后处理器为任何使用@Repository
注释的 bean 添加一个顾问程序,以便捕获任何特定于平台的异常,然后将其作为 Spring 未经检查的数据访问异常之一重新抛出。
@Controller
@Controller
注释指示特定类充当控制器的角色。 @Controller
注释充当带注释的类的@Controller
型,指示其角色。
@Controller 有什么特别之处?
我们无法将此注释与@Service
或@Repository
等任何其他注释切换,即使它们看起来相同。调度程序扫描使用@Controller
注释的类,并检测其中的@RequestMapping
注释。我们只能在@Controller
注释类上使用@RequestMapping
。
@服务
@Services
在存储库层中保存业务逻辑和调用方法。
@Service 有什么特别之处?
除了它用于表明它持有业务逻辑这一事实之外,这个注释没有明显的特点,但是谁知道,spring 可能在未来增加一些额外的特殊功能。
还有什么?
与上面类似,将来 Spring 可能会根据它们的分层约定选择为@Service
@Controller
, @Repository
@Controller
和@Repository
添加特殊功能。因此,尊重惯例并将其与层一致使用始终是一个好主意。
它们几乎相同 - 所有这些都意味着该类是一个 Spring bean。 @Service
@Controller
, @Repository
和@Controller
是专门的@Component
。您可以选择使用它们执行特定操作。例如:
@Controller
bean @Repository
bean 有资格进行持久性异常转换另一件事是你在语义上将组件指定给不同的层。
@Component
提供的一件事是你可以用它来注释其他注释,然后以与@Service
相同的方式使用它们。
例如最近我做了:
@Component
@Scope("prototype")
public @interface ScheduledJob {..}
因此,所有使用@ScheduledJob
注释的类都是 spring bean,除此之外还注册为 quartz 作业。您只需提供处理特定注释的代码即可。