Java批注在2004年随Java 5一起引入,是一种将元数据添加到Java源代码中的方法。 如今,许多主要框架(如Spring或Hibernate)都严重依赖注释。
在本文中,我们将介绍一个非常有用的Spring功能,该功能允许我们基于一个或多个Spring注释创建自己的注释。
编写自定义注释
假设我们有一组经常一起使用的Spring注释。 一个常见的示例是@Service和@Transactional的组合:
@Service @Transactional (rollbackFor = Exception. class , timeout = 5 ) public class UserService { ... }
不必一遍又一遍地重复两个注释,我们可以创建包含这两个Spring注释的自己的注释。 创建我们自己的注释非常简单,如下所示:
@Service @Transactional (rollbackFor = Exception. class , timeout = 5 ) @Retention (RetentionPolicy.RUNTIME) public @interface MyService {}
注释是使用@interface关键字定义的(而不是类或接口)。 标准Java注释@Retention用于指示注释应在运行时可处理。 我们还将两个Spring注释都添加到了注释中。
现在,我们可以使用自己的@MyService批注来批注我们的服务:
@MyService public class UserService { ... }
Spring现在检测到@MyService被@Service和@Transactional注释,并提供与前面的示例相同的行为,并且在UserService类中存在两个注释。
请注意,这是Spring注释处理方式的功能,而不是一般的Java功能。 如果将其他框架和库的注释添加到自己的注释中,则它们可能无法正常工作。
用例范例
自定义注释可以在各种情况下使用,以提高代码的可读性。 这是另外两个可能派上用场的例子。
也许我们在代码的各个位置都需要一个属性值。 通常使用Spring的@Value注释注入属性:
// injects configuration properties my.api.key @Value ( "${my.api.key}" ) private String apiKey;
在这种情况下,我们可以将属性表达式从代码中移到单独的注释中:
@Value ( "${my.api.key}" ) @Retention (RetentionPolicy.RUNTIME) public @interface ApiKey {}
现在,在我们的代码中,我们可以使用@ApiKey而不是在各处重复属性表达式:
@ApiKey private String apiKey;
另一个例子是集成测试。 在测试中,通常使用各种Spring批注来定义测试设置。 可以使用自定义注释将这些注释分组在一起。 例如,我们可以创建一个@MockMvcTest注释,该注释定义模拟mvc测试的Spring设置:
@SpringBootTest @AutoConfigureMockMvc (secure = false ) @TestPropertySource (locations = "classpath:test.properties" ) @ExtendWith (SpringExtension. class ) @Retention (RetentionPolicy.RUNTIME) public @interface MockMvcTest {}
现在,我们的测试定义看起来更加清晰。 我们只需要添加@MockMvcTest即可获得完整的测试设置:
@MockMvcTest public class MyTest { ... }
请注意,我们的@MockMvcTest批注还包含JUnit 5的@ExtendWith批注。与Spring一样,如果将其添加到您自己的自定义批注中,JUnit 5也能够检测到此批注。 请注意,如果仍在使用JUnit 4,这将无法正常工作。对于JUnit 4,您必须使用@RunWith而不是@ExtendWith。 不幸的是,@RunWith仅在直接放在测试类中时才起作用。
春天的例子
Spring在各种情况下都使用此功能来定义常用注释的快捷方式。
这里有一些例子:
- @GetMapping是@RequestMapping的简短版本(方法= {RequestMethod.GET})。
- @RestController是@Controller和@ResponseBody的组合。
- @SpringBootApplication是@ SpringBootConfiguration,@ EnableAutoConfiguration和@ComponentScan的快捷方式
您可以通过查看Spring源代码中这些注释的定义来自己验证。
翻译自: https://www.javacodegeeks.com/2020/02/composing-custom-annotations-with-spring.html