利用 Spring Boot 的属性支持增强您的应用程序

工程 | Greg L. Turnquist | 2013 年 10 月 30 日 | ...

Spring Boot 正在持续发展壮大。上个月我写了一篇关于 通过 pull request 为 Spring Boot 贡献代码 的文章。我深入研究了 Spring Boot 的内部机制,展示了其令人难以置信的自动配置功能和 CLI 支持。

在这篇文章中,我想深入探讨 Spring Boot 对属性的强大支持。属性虽然小巧,并不十分显眼,但却能以非常实用的方式快速增强您的应用程序。在这篇文章中,我将逐步讲解 我如何在之前的博客文章中编写的 Spring JMS 支持中添加属性支持

什么是属性?

属性本质上是外部化应用程序设置的方法。您可能会在应用程序中嵌入特定的信息,但由于多种原因,您以后可能需要更改它。

  • 您的默认配置是基于生产环境的(主机名、端口等),但是您需要在测试环境中使用不同的主机名来覆盖它。
  • 您可以配置应用程序使用池,但是想要调整池的大小。
  • 您需要一个“超级秘密”密钥提供给您的应用程序,也许是一个 OAuth 密钥,并且您不想在发布的应用程序中放置默认密钥。

所有这些用例都需要不同的方法在应用程序启动时提供自定义设置。Spring Boot 来救援!

Spring JMS 和属性

足够的抽象用例。让我们来看一个 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` 的代码片段展示了几个关键组件。

  • `@EnableConfigurationProperties` 利用 `JmsTemplateProperties` 作为属性来源,并使其可用于整个类。
  • `@ConfigurationProperties(name = "spring.jms")` 标记 `JmsTemplateProperties` 类,它将作为属性的持有者。“spring.jms”作为前缀,该类的每个属性都成为目标属性。

我只需要创建一个 **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://127.0.0.1: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://127.0.0.1";
			}
			else {
				return this.brokerURL;
			}
		}
    . . .

默认情况下,Spring Boot 将创建一个 ActiveMQ 连接工厂,除非您提供 您自己的连接工厂

  • `ActiveMQConnectionFactoryCreator` 已用 `@EnableConfigurationProperties` 标记。
  • 我们可以覆盖 **brokerURL**、**inMemory** 和 **pooled**。

在 `ActiveMQConnectionFactoryCreator` 中,如果设置了 **pooled**,则它将创建一个 **PooledConnectionFactory**。如果设置了 **inMemory**,则它将使用 `vm://127.0.0.1`。但是将其更改为 false 将导致连接工厂切换到使用 brokerURL。

到目前为止,这些属性都是通过它们各自的 getter 方法访问的。但这并不是唯一的方法。Spring 提供了一个强大的 `@Value` 注解,用于从多个来源注入数据,包括属性。

这就是我对 为 Spring Boot 贡献 Spring JMS 属性支持 的大部分工作。

让我们看看更多使用 Spring Boot 属性支持的方法。

超级秘密的 GitHub oauth 数据

我一直在开发一个小型应用程序,用于快速列出针对各种 入门指南 的所有未解决问题。它使用 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 的属性支持变得超级容易。

使用更多属性覆盖属性

这还不是全部。我可以将一个 application.properties 文件嵌入到我分发的 JAR 文件中,提供默认设置。

但是如果我需要覆盖任何内容,我只需要创建一个 _另一个_ 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 通过属性设置使我们的应用程序灵活且可配置的惊人能力。这是一个范围可能很小但非常有用的工具。

祝您编程愉快!

获取 Spring Newsletter

通过 Spring Newsletter 保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring在一个简单的订阅中提供对OpenJDK™、Spring和Apache Tomcat®的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部