在上一节的LicenseService类中,读者可能已经注意到,在getLicense()中使用了来自config.getExampleProperty()的值来设置license.withComment()的值。所指的代码如下:
public License getLicense(String organizationId,String licenseId) {
License license = licenseRepository.findByOrganizationIdAndLicenseId( organizationId, licenseId);
return license.withComment(config.getExampleProperty());
}
如果查看licensing-service/src/main/java/com/thoughtmechanix/licenses/config/ServiceConfig.java,
将看到使用@Value注解标注的属性。代码清单3-9展示了@Value注解的用法。
代码清单3-9 用于集中应用程序属性的ServiceConfig类
package com.thoughtmechanix.licenses.config;
import org.springframework.beans.factory.annotation.Value;
@Component
public class ServiceConfig{
@Value("${example.property}")
private String exampleProperty;
public String getExampleProperty(){
return exampleProperty;
}
}
虽然Spring Data“自动神奇地”将数据库的配置数据注入数据库连接对象中,但所有其他属性都必须使用@Value注解进行注入。
在上述示例中,@Value注解从Spring Cloud配置服务器中提取example.property并将其注入ServiceConfig类的example.property属性中。
提示
虽然可以将配置的值直接注入各个类的属性中,但我发现将所有配置信息集中到一个配置类,然后将配置类注入需要它的地方是很有用的。
3.3.5 使用Spring Cloud配置服务器和Git
如前所述,使用文件系统作为Spring Cloud配置服务器的后端存储库,对基于云的应用程序来说是不切实际的,
因为开发团队必须搭建和管理所有挂载在云配置服务器实例上的共享文件系统。
Spring Cloud配置服务器能够与不同的后端存储库集成,这些存储库可以用于托管应用程序配置属性。
我成功地使用过Spring Cloud配置服务器与Git源代码控制存储库集成。
通过使用Git,我们可以获得将配置管理属性置于源代码管理下的所有好处,
并提供一种简单的机制来将属性配置文件的部署集成到构建和部署管道中。
要使用Git,需要在配置服务的bootstrap.yml文件中使用代码清单3-10所示的配置替换文件系统的配置。
代码清单3-10 Spring Cloud配置的bootstrap.yml
server:
port: 8888
spring:
cloud:
config:
server:
git: ⇽--- 告诉Spring Cloud Config使用Git作为后端存储库
uri: https://github.com/carnellj/config-repo/ ⇽--- 告诉Spring Cloud Git服务器和Git存储库的URL searchPaths: licensingservice,organizationservice ⇽告诉Spring Cloud Config在Git中查找配置文件的路径
username: native-cloud-apps
password: 0ffended
上述示例中的3个关键配置部分是spring.cloud.config.server、spring.cloud. config.server.git.uri和spring.cloud.config.server.git.searchPaths属性。spring.cloud.config.server属性告诉Spring Cloud配置服务器使用非基于文件系统的后端存储库。在上述例子中,将要连接到基于云的Git存储库GitHub。
spring.cloud.config.server.git.uri属性提供要连接的存储库URL。最后,spring. cloud.config.server.git.searchPaths属性告诉Spring Cloud Config服务器在云配置服务器启动时应该在Git存储库中搜索的相对路径。与配置的文件系统版本一样,spring.cloud. config.server.git.seachPaths属性中的值是以逗号分隔的由配置服务托管的服务列表。
3.3.6 使用Spring Cloud配置服务器刷新属性
开发团队想要使用Spring Cloud配置服务器时,遇到的第一个问题是,如何在属性变化时动态刷新应用程序。
Spring Cloud配置服务器始终提供最新版本的属性,通过其底层存储库,对属性进行的更改将是最新的。
但是,Spring Boot应用程序只会在启动时读取它们的属性,因此Spring Cloud配置服务器中进行的属性更改不会被Spring Boot应用程序自动获取。Spring Boot Actuator提供了一个@RefreshScope注解,
允许开发团队访问/refresh端点,这会强制Spring Boot应用程序重新读取应用程序配置。
代码清单3-11展示了@RefreshScope注解的作用。
代码清单3-11 @RefreshScope注解
package com.thoughtmechanix.licenses;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
@SpringBootApplication
@RefreshScope
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
我们需要注意一些有关@RefreshScope注解的事情。首先,注解只会重新加载应用程序配置中的自定义Spring属性。
Spring Data使用的数据库配置等不会被@RefreshScope注解重新加载。
要执行刷新,可以访问http://<yourserver>:8080/refresh端点。
关于刷新微服务
将微服务与Spring Cloud配置服务一起使用时,在动态更改属性之前需要考虑的一件事是,可能会有同一服务的多个实例正在运行,
需要使用新的应用程序配置刷新所有这些服务。有几种方法可以解决这个问题。
Spring Cloud配置服务确实提供了一种称为Spring Cloud Bus的“推送”机制,
使Spring Cloud配置服务器能够向所有使用服务的客户端发布有更改发生的消息。
Spring Cloud配置需要一个额外的中间件(RabbitMQ)运行。
这是检测更改的非常有用的手段,但并不是所有的Spring Cloud配置后端都支持这种“推送”机制(也就是Consul服务器)。
在下一章中,我们将使用Spring Service Discovery和Eureka来注册所有服务实例。
我用过的用于处理应用程序配置刷新事件的一种技术是,刷新Spring Cloud配置中的应用程序属性,
然后编写一个简单的脚本来查询服务发现引擎以查找服务的所有实例,并直接调用/refresh端点。
最后一种方法是重新启动所有服务器或容器来接收新的属性。这项工作很简单,特别是在Docker等容器服务中运行服务时。
重新启动Docker容器差不多需要几秒,然后将强制重新读取应用程序配置。
记住,基于云的服务器是短暂的。不要害怕使用新配置启动服务的新实例,直接使用新服务,然后拆除旧的服务。