领先一步
VMware 提供培训和认证,助你加速前进。
了解更多Spring Boot 正在持续发展壮大。上个月我写了 通过拉取请求贡献 Spring Boot。我深入探讨了 Spring Boot 的各个层面,展示了它令人难以置信的自动配置特性和 CLI 支持。
在这篇文章中,我想深入探讨 Spring Boot 对属性的强大支持。属性虽然看似微不足道,不那么显眼,但却能以非常实际的方式迅速增强你的应用程序。在这篇文章中,我将逐步讲解我是如何为我在上一篇博文中编写的 Spring JMS 支持添加属性支持的。
属性本质上是将应用程序设置外部化的方式。你可能在应用程序中硬编码了一些信息,但出于多种原因,你希望以后能够更改它。
所有这些用例都强烈需要一种不同的方式来在应用程序启动时提供定制的设置。Spring Boot 帮你解决了这个问题!
抽象的用例就到此为止。让我们看看 Spring Boot 如何支持属性的真实示例!我们将更深入地研究 Spring JMS 支持。
@Configuration
@ConditionalOnClass({ JmsTemplate.class, ConnectionFactory.class })
@EnableConfigurationProperties(JmsTemplateProperties.class)
public class JmsTemplateAutoConfiguration {
@Autowired
private JmsTemplateProperties config;
. . .
@ConfigurationProperties(name = "spring.jms")
public static class JmsTemplateProperties {
private boolean pubSubDomain = true;
public boolean isPubSubDomain() {
return this.pubSubDomain;
}
public void setPubSubDomain(boolean pubSubDomain) {
this.pubSubDomain = pubSubDomain;
}
}
. . .
这段来自 Spring Boot 的 JmsTemplatAutoConfiguration
代码片段展示了几个关键组件。
我只需要创建一个 application.properties 文件并为其赋值即可。
spring.jms.pubSubDomain=true
在该文件的更下方,还有内置连接工厂的属性。
@Configuration
@ConditionalOnClass(ActiveMQConnectionFactory.class)
@ConditionalOnMissingBean(ConnectionFactory.class)
@EnableConfigurationProperties(ActiveMQConnectionFactoryProperties.class)
protected static class ActiveMQConnectionFactoryCreator {
@Autowired
private ActiveMQConnectionFactoryProperties config;
@Bean
ConnectionFactory jmsConnectionFactory() {
if (this.config.isPooled()) {
PooledConnectionFactory pool = new PooledConnectionFactory();
pool.setConnectionFactory(new ActiveMQConnectionFactory(this.config
.getBrokerURL()));
return pool;
}
else {
return new ActiveMQConnectionFactory(this.config.getBrokerURL());
}
}
}
@ConfigurationProperties(name = "spring.activemq")
public static class ActiveMQConnectionFactoryProperties {
private String brokerURL = "tcp://localhost:61616";
private boolean inMemory = true;
private boolean pooled = false;
// Will override brokerURL if inMemory is set to true
public String getBrokerURL() {
if (this.inMemory) {
return "vm://localhost";
}
else {
return this.brokerURL;
}
}
. . .
默认情况下,Spring Boot 将创建一个 ActiveMQ 连接工厂,除非你提供自己的。
ActiveMQConnectionFactoryCreator
已被标记为 @EnableConfigurationProperties
。在 ActiveMQConnectionFactoryCreator
中,如果设置了 pooled,它会创建一个 PooledConnectionFactory。如果设置了 inMemory,它会使用 vm://localhost。但将其设置为 false 会导致连接工厂切换为使用 brokerURL。
到目前为止,这些属性都是通过各自的 getter 访问的。但这并非唯一的方法。Spring 提供了一个强大的 @Value
注解,可以从包括属性在内的多个源注入数据。
这便是我为 Spring Boot 贡献 Spring JMS 属性支持的主要工作。
让我们看看更多使用 Spring Boot 属性支持的方式。
我一直在开发一个小应用程序,用于快速列出针对各种入门指南 (Getting Started guides) 的所有未解决问题。它使用 Spring Social GitHub 来查询问题。为了获取我需要的数据,它强大的 GitHubTemplate
需要一个 OAuth 密钥。
@Controller
@Log
class IssueAggregator implements CommandLineRunner {
/**
* This needs to be supplied by application.properties, a file NOT to be put under source control
*/
@Value('${token}')
String githubToken
@Bean
GitHubTemplate githubTemplate() {
new GitHubTemplate(githubToken)
}
. . .
正如你所猜测的,githubToken
是通过 @Value('${token}')
填充的。如果你仔细观察,会注意到没有默认值。那是因为我不会提供一个默认值。任何需要此应用程序副本的人都必须提供他们自己的秘密 OAuth 密钥,如注释中所述。
注意:这是 Groovy 代码,但相同的注解也适用于 Java(你只需要双引号)。Spring Boot 只是让利用 Spring Framework 的属性支持变得超级容易。
不止如此。我可以在我分发的 JAR 文件中嵌入一个 application.properties 文件,提供默认设置。
但如果我需要覆盖任何设置,我只需创建另一个 application.properties 文件并将其放置在 JAR 文件旁边。Spring Boot 会首先读取内部的 application.properties 文件,然后自动找到外部的文件。
最后,它还会读取使用 Java 的 -Dspring.activemq.inMemory=false
命令行指令提供的属性。这提供了第三种覆盖设置的方式。
附注:对于使用 Windows 的开发者,Spring Boot 提供额外的特殊支持,将诸如 SPRING_ACTIVEMQ_INMEMORY
、spring-activemq-inmemory
和 springActivemqInmemory
等映射到同一个目标:spring.activemq.inMemory。这有助于解决特定平台问题,例如环境变量不支持点号。
希望你现在能够理解 Spring Boot 通过属性设置使我们的应用程序变得灵活和可配置的惊人能力。它可能是一个范围很小的工具,但却非常实用。
编码愉快!