5.2 Building our Spring Cloud configuration server

5.2.2 Using Spring Cloud configuration server with the filesystem

依赖

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.2.4.RELEASE</version>
  5. <relativePath/> <!-- lookup parent from repository -->
  6. </parent>
  7. <dependencies>
  8. <dependency>
  9. <groupId>org.springframework.cloud</groupId>
  10. <artifactId>spring-cloud-config-server</artifactId>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-actuator</artifactId>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.springframework.boot</groupId>
  18. <artifactId>spring-boot-starter-test</artifactId>
  19. <scope>test</scope>
  20. </dependency>
  21. </dependencies>

基本配置文件

  1. spring:
  2. application:
  3. name: config-server
  4. server:
  5. port: 8071

基于文件系统存储的配置
native:表示配置文件将从classpath或filesystem中获取

  1. spring:
  2. application:
  3. name: config-server
  4. profiles:
  5. active: native
  6. cloud:
  7. config:
  8. server:
  9. native:
  10. search-locations:
  11. - file:///Users/illary.huaylupo
  12. server:
  13. port: 8071
  1. server:
  2. native:
  3. search-locations:
  4. - classpath:/config

5.2.3 Setting up the configuration files for a service

在resources下创建config目录,并添加两个properties文件,如下图
image.png

  1. example.property= I AM THE DEFAULT
  2. spring.jpa.hibernate.ddl-auto=none
  3. spring.jpa.database=POSTGRESQL
  4. spring.datasource.platform=postgres
  5. spring.jpa.show-sql = true
  6. spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
  7. spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
  8. spring.database.driverClassName= org.postgresql.Driver
  9. spring.datasource.testWhileIdle = true
  10. spring.datasource.validationQuery = SELECT 1
  11. management.endpoints.web.exposure.include=*
  12. management.endpoints.enabled-by-default=true
  1. example.property= I AM DEV
  2. # DataSource settings: set here your own configurations for the database
  3. spring.datasource.url = jdbc:postgresql://101.132.251.198:5432/test
  4. spring.datasource.username = postgres
  5. spring.datasource.password = root

启动项目并访问:http://localhost:8071/licensing-service/default
image.png
如果访问:http://localhost:8071/licensing-service/dev
image.png
查找dev的时候,会把default的属性一起查找出来,这是因为spring有个等级机制,当查找配置文件的时候,总是会优先找default的配置文件,然后再找相应的特定环境的文件,如果有属性冲突,就会覆盖默认的。

5.3 Integrating Spring Cloud Config with a Spring Boot Client

5.3.1 Setting up the licensing service spring cloud config service dependencies

添加依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.cloud</groupId>
  8. <artifactId>spring-cloud-starter-config</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.springframework.boot</groupId>
  12. <artifactId>spring-boot-starter-data-jpa</artifactId>
  13. </dependency>
  14. <dependency>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-actuator</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.postgresql</groupId>
  20. <artifactId>postgresql</artifactId>
  21. <version>42.3.1</version>
  22. </dependency>
  23. </dependencies>

5.3.2 Configuration the licensing service to use Spring Cloud Config

配置文件

  1. spring:
  2. application:
  3. name:
  4. licensing-service
  5. profiles:
  6. active: dev
  7. cloud:
  8. config:
  9. uri: http://localhost:8071

启动项目并访问:http://localhost:8080/actuator/env
image.png

5.3.3 Wiring in a data source using Spring Cloud configuration server

引入依赖:

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-hateoas</artifactId>
  8. </dependency>

实体类:

  1. @Data
  2. @Entity
  3. @Table(name = "licenses")
  4. public class License extends RepresentationModel<License> {
  5. @Id
  6. @Column(name = "license_id", nullable = false)
  7. private String licenseId;
  8. private String description;
  9. @Column(name = "organization_id", nullable = false)
  10. private String organizationId;
  11. @Column(name = "product_name", nullable = false)
  12. private String productName;
  13. @Column(name = "license_type", nullable = false)
  14. private String licenseType;
  15. @Column(name = "comment")
  16. private String comment;
  17. public License withComment(String comment) {
  18. this.setComment(comment);
  19. return this;
  20. }
  21. }

如果java类中的属性和数据库中表的字段属性相同,就可以不加@Column 注解

LicenseRepository interface定义:

  1. @Repository
  2. public interface LicenseRepository extends CrudRepository<License, String> {
  3. List<License> findByOrganizationId(String organizationId);
  4. License findByOrganizationIdAndLicenseId(String organizationId, String licenseId);
  5. }

LicenseService定义:

  1. @Service
  2. public class LicenseService {
  3. @Autowired
  4. MessageSource messageSource;
  5. @Autowired
  6. private LicenseRepository licenseRepository;
  7. @Autowired
  8. ServiceConfig config;
  9. public License getLicense(String licenseId, String organizationId) {
  10. License license = licenseRepository.findByOrganizationIdAndLicenseId(licenseId, organizationId);
  11. if (null == license) {
  12. throw new IllegalArgumentException(String.format(messageSource.getMessage("license.search.error.message", null, null), licenseId, organizationId));
  13. }
  14. return license.withComment(config.getExampleProperty());
  15. }
  16. public License updateLicense(License license) {
  17. licenseRepository.save(license);
  18. return license.withComment(config.getExampleProperty());
  19. }
  20. public String deleteLicense(String licenseId) {
  21. String responseMessage = null;
  22. License license = new License();
  23. license.setLicenseId(licenseId);
  24. licenseRepository.delete(license);
  25. responseMessage = String.format(messageSource.getMessage("license.delete.message", null, null), licenseId);
  26. return responseMessage;
  27. }
  28. }

5.3.4 Directly reading properties using the @Value annotation

上述代码中引用了config.getExampleProperty()方法

  1. public License updateLicense(License license) {
  2. licenseRepository.save(license);
  3. return license.withComment(config.getExampleProperty());
  4. }

该方法的细节:

  1. @Component
  2. public class ServiceConfig {
  3. @Value("${example.property}")
  4. private String exampleProperty;
  5. public String getExampleProperty() {
  6. return exampleProperty;
  7. }
  8. }

5.3.5 Refreshing your properties using Spring Cloud configuration server

为了改变配置的时候,动态的做出反应,需要在启动类上添加一个@RefreshScope

  1. @SpringBootApplication
  2. @RefreshScope
  3. public class LicensingApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(LicensingApplication.class, args);
  6. }
  7. }

@RefreshScope该注解只会动态加载在配置文件中自定义的属性,像database configuration这样的配置不会动态的加载。为了执行refresh其他的属性,可以访问
http://:8080/refresh 端点

5.3.6 Using Spring Cloud configuration server with Git

在配置服务中的bootstrap.yml中添加:
image.png

5.4 Protecting sensitive configuration information

5.4.1 Setting up a symmetric encryption key

在配置服务模块的bootstrap.yml中添加:
image.png

5.4.2 Encrypting and decrypting a property

image.png
根据上述的步骤,可以将配置文件中需要加密的属性值加密
image.png
{cipher}告诉spring cloud配置服务,处理的是一个加密的值