使用Profiles

    • native
    • test
    • production

    或者按git分支定义master、dev这些环境:

    • master
    • dev

    在启动一个Spring应用程序的时候,可以传入一个或多个环境,例如:

    大多数情况下,使用一个环境就足够了。

    Spring Boot对Profiles的支持在于,可以在中为每个环境进行配置。下面是一个示例配置:

    1. spring:
    2. application:
    3. name: ${APP_NAME:unnamed}
    4. datasource:
    5. url: jdbc:hsqldb:file:testdb
    6. username: sa
    7. password:
    8. dirver-class-name: org.hsqldb.jdbc.JDBCDriver
    9. hikari:
    10. auto-commit: false
    11. connection-timeout: 3000
    12. validation-timeout: 3000
    13. max-lifetime: 60000
    14. maximum-pool-size: 20
    15. minimum-idle: 1
    16. pebble:
    17. suffix:
    18. cache: false
    19. server:
    20. port: ${APP_PORT:8080}
    21. spring:
    22. profiles: test
    23. server:
    24. port: 8000
    25. ---
    26. spring:
    27. profiles: production
    28. server:
    29. port: 80
    30. pebble:
    31. cache: true

    注意到分隔符---,最前面的配置是默认配置,不需要指定Profile,后面的每段配置都必须以spring.profiles: xxx开头,表示一个Profile。上述配置默认使用8080端口,但是在test环境下,使用8000端口,在production环境下,使用80端口,并且启用Pebble的缓存。

    要以test环境启动,可输入如下命令:

    1. $ java -Dspring.profiles.active=test -jar springboot-profiles-1.0-SNAPSHOT.jar
    2. . ____ _ __ _ _
    3. /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
    4. ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
    5. \\/ ___)| |_)| | | | | || (_| | ) ) ) )
    6. ' |____| .__|_| |_|_| |_\__, | / / / /
    7. =========|_|==============|___/=/_/_/_/
    8. :: Spring Boot :: (v2.3.0.RELEASE)
    9. 2020-06-13 11:24:45.020 INFO 73987 --- [ main] com.itranswarp.learnjava.Application : Starting Application v1.0-SNAPSHOT on ... with PID 73987 ...
    10. 2020-06-13 11:24:45.022 INFO 73987 --- [ main] com.itranswarp.learnjava.Application : The following profiles are active: test
    11. ...
    12. 2020-06-13 11:24:47.533 INFO 73987 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8000 (http) with context path ''

    从日志看到活动的Profile是test,Tomcat的监听端口是8000

    通过Profile可以实现一套代码在不同环境启用不同的配置和功能。假设我们需要一个存储服务,在本地开发时,直接使用文件存储即可,但是,在测试和生产环境,需要存储到云端如S3上,如何通过Profile实现该功能?

    首先,我们要定义存储接口StorageService

    本地存储可通过LocalStorageService实现:

    1. @Component
    2. @Profile("default")
    3. public class LocalStorageService implements StorageService {
    4. String localStorageRootDir;
    5. final Logger logger = LoggerFactory.getLogger(getClass());
    6. private File localStorageRoot;
    7. @PostConstruct
    8. public void init() {
    9. logger.info("Intializing local storage with root dir: {}", this.localStorageRootDir);
    10. this.localStorageRoot = new File(this.localStorageRootDir);
    11. }
    12. @Override
    13. public InputStream openInputStream(String uri) throws IOException {
    14. File targetFile = new File(this.localStorageRoot, uri);
    15. return new BufferedInputStream(new FileInputStream(targetFile));
    16. }
    17. @Override
    18. public String store(String extName, InputStream input) throws IOException {
    19. String fileName = UUID.randomUUID().toString() + "." + extName;
    20. File targetFile = new File(this.localStorageRoot, fileName);
    21. try (OutputStream output = new BufferedOutputStream(new FileOutputStream(targetFile))) {
    22. input.transferTo(output);
    23. }
    24. return fileName;
    25. }

    注意到LocalStorageService使用了条件装配@Profile("default"),即默认启用LocalStorageService,而CloudStorageService使用了条件装配@Profile("!default"),即非default环境时,自动启用。这样,一套代码,就实现了不同环境启用不同的配置。

    从下载练习:使用Profile启动Spring Boot应用 (推荐使用快速下载)

    Spring Boot允许在一个配置文件中针对不同Profile进行配置;

    Spring Boot在未指定Profile时默认为default

    使用Profiles - 图1