如果您一直在使用 Java 和 Spring Boot,我相信您已经遇到过该@Value
注释。我在这里向您展示一种替代方法——这比使用@Value
现有方法要好得多。
我们看一下@Value
Spring中的经典注解,它可能是这样的:
该@Value
注释可用于将值注入到 Spring 托管 bean 中。在此示例中,我们有一个服务负责管理JSON Web 令牌(简称JWT)。
在这里,我们尝试从文件中注入客户端密钥application.properties
。秘密在于配置,而不是我们想要硬编码的东西。
DEFAULT_SECRET
如果未找到该属性,我们还为常量定义了一个默认值。
那么这种方法有什么缺点呢?
以下是使用这种方法的三个主要缺点。我将在下面更详细地讨论每一项。
-
配置和服务实现没有分离。我们需要外部化的配置。
-
破坏可测试性。
-
灵活性较差,更容易出错。
通过@Value
在服务和 bean 中使用注释,我们将配置与服务实现混合在一起。
我们将把配置分散到我们的应用程序中。很难看出我们的应用程序运行实际需要什么配置以及它在哪里。
在我正在从事的一个大项目中,我自己就是这个问题的受害者。我和我的团队正在努力将大部分代码从现有的微服务转移到我们正在构建的新服务中。我们的配置遍布各处,具有不同的名称前缀。整合和更新所有属性名称以匹配新的服务包名称非常混乱。
在我们的代码中使用的另一个缺点@Value
是它破坏了可测试性。这些属性将由 spring 自动注入,因此首先我们需要运行测试中的 spring 上下文(这会导致单元测试缓慢)。
其次,如果我们想使用不同的属性设置进行测试怎么办?通常我们可以单独进行application.properties
测试,但如果我们想使用不同的值进行测试,它可能会变得混乱。
有一种方法可以解决这个问题,即使用@Autowired
构造函数并通过构造函数注入属性。但是您需要将它们一一注入,因此构造函数可能会变得又长又乱。
第三个缺点是该@Value
方法不太灵活,并且没有对验证数据的内置支持。
我们应该做什么呢?
Spring Boot 提供了一种叫做 的东西@ConfigurationProperties
来分离和外部化配置。让我展示一下它是如何工作的。
这是相同的示例,但使用配置属性。您可以看到我们有一个前缀,它将是所有属性(变量)名称之前的名称前缀。
例如,在 中,application.properties
我们可以通过设置来设置客户端密钥com.example.demo.client-secret = something secret
。
我们还提供了一个默认值,如前面的示例所示。
我们使用 Lombok
@Data
注释来生成 getter 和 setter,而不是自己输入它们。
现在最酷的是,这个配置只是一个 POJO(普通旧 Java 对象),我们可以通过构造函数将其注入到我们的服务类中。
服务不需要知道配置来自哪里。它不应该处理属性的底层源。它只需要属性类的一个实例,就可以了。
这使得它在单元测试中非常易于使用,您只需使用一些值填充配置类并注入它即可。
您可以使用配置属性做一些很酷的事情
我们还可以组合属性值。您可以在属性文件中单独输入数据库 URL 和端口,但在配置类中您可以创建一个 getter 将它们连接在一起以提供服务。
配置属性还支持通过包验证属性spring-boot-starter-validation
。
这将确保配置属性在加载之前符合所需的格式。超级整洁。
此外,由于配置类是一个 Spring bean,您可以创建它们的多个实现并使用不同的配置文件,并为测试和生产提供唯一的默认值 – 作为示例。
就是这样。希望它能帮助您了解使用@ConfigurationProperties
而不是@Value
.
原文始发于微信公众号(编译):为什么你应该停止在 Spring 中使用 @Value 注解(并改用它)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/253591.html