SpringBoot profile运用

非 Y 不嫁゛ 提交于 2020-02-29 09:41:13

摘要: Spring Boot使用@Profile注解可以实现不同环境下配置参数的切换,任何@Component或@Configuration注解的类都可以使用@Profile注解。 例如: @Configuration @Profile("production") public class Produc...

Spring Boot使用@Profile注解可以实现不同环境下配置参数的切换,任何@Component@Configuration注解的类都可以使用@Profile注解。

例如:

  1.  
    @Configuration
  2.  
    @Profile("production")
  3.  
    public class ProductionConfiguration {
  4.  
    // ...
  5.  
    }

通常,一个项目中可能会有多个profile场景,例如下面为test场景:

  1.  
    @Configuration
  2.  
    @Profile("test")
  3.  
    public class TestConfiguration {
  4.  
    // ...
  5.  
    }

在存在多个profile情况下,你可以使用spring.profiles.active来设置哪些profile被激活。spring.profiles.include属性用来设置无条件的激活哪些profile。

例如,你可以在application.properties中设置:

spring.profiles.active=dev,hsqldb

或者在application.yaml中设置:

spring.profiles.active:dev,hsqldb

spring.profiles.active属性可以通过命令行参数或者资源文件来设置,其查找顺序,请参考Spring Boot特性

自定义Profile注解

@Profile注解需要接受一个字符串,作为场景名。这样每个地方都需要记住这个字符串。Spring的@Profile注解支持定义在其他注解之上,以创建自定义场景注解。

  1.  
    @Target({ElementType.TYPE, ElementType.METHOD})
  2.  
    @Retention(RetentionPolicy.RUNTIME)
  3.  
    @Profile("dev")
  4.  
    public @interface Dev {
  5.  
    }

这样就创建了一个@Dev注解,该注解可以标识bean使用于@Dev这个场景。后续就不再需要使用@Profile("dev")的方式。这样即可以简化代码,同时可以利用IDE的自动补全:)

多个Profile例子

下面是一个例子:

  1.  
    package com.javachen.example.service;
  2.  
     
  3.  
    public interface MessageService {
  4.  
    String getMessage();
  5.  
    }

对于MessageService接口,我们可以有生产和测试两种实现:

  1.  
    package com.javachen.example.service;
  2.  
     
  3.  
    import org.springframework.beans.factory.annotation.Value;
  4.  
    import org.springframework.context.annotation.Profile;
  5.  
    import org.springframework.stereotype.Component;
  6.  
     
  7.  
    @Component
  8.  
    @Profile({ "dev" })
  9.  
    public class HelloWorldService implements MessageService{
  10.  
     
  11.  
    @Value("${name:World}")
  12.  
    private String name;
  13.  
     
  14.  
    public String getMessage() {
  15.  
    return "Hello " + this.name;
  16.  
    }
  17.  
     
  18.  
    }
  1.  
    package com.javachen.example.service;
  2.  
     
  3.  
    import org.springframework.beans.factory.annotation.Value;
  4.  
    import org.springframework.context.annotation.Profile;
  5.  
    import org.springframework.stereotype.Component;
  6.  
     
  7.  
    @Component
  8.  
    @Profile({ "prod" })
  9.  
    public class GenericService implements MessageService {
  10.  
     
  11.  
    @Value("${hello:Hello}")
  12.  
    private String hello;
  13.  
     
  14.  
    @Value("${name:World}")
  15.  
    private String name;
  16.  
     
  17.  
    @Override
  18.  
    public String getMessage() {
  19.  
    return this.hello + " " + this.name;
  20.  
    }
  21.  
     
  22.  
    }

Application类为:

  1.  
    @SpringBootApplication
  2.  
    public class Application implements CommandLineRunner {
  3.  
    private static final Logger logger = LoggerFactory.getLogger(Application.class);
  4.  
     
  5.  
    @Autowired
  6.  
    private MessageService messageService;
  7.  
     
  8.  
    @Override
  9.  
    public void run(String... args) {
  10.  
    logger.info(this.messageService.getMessage());
  11.  
    if (args.length > 0 && args[0].equals("exitcode")) {
  12.  
    throw new ExitException();
  13.  
    }
  14.  
    }
  15.  
     
  16.  
    public static void main(String[] args) throws Exception {
  17.  
    SpringApplication.run(Application.class, args);
  18.  
    }
  19.  
    }

实际使用中,使用哪个profile由spring.profiles.active控制,你在resources/application.properties中定义spring.profiles.active=XXX,或者通过-Dspring.profiles.active=XXXXXX可以是dev或者prod或者dev,prod需要注意的是:本例中是将@Profile用在Service类上,一个Service接口不能同时存在超过两个实现类,故本例中不能同时使用dev和prod。

通过不同的profile,可以有对应的资源文件application-{profile}.properties。例如,application-dev.properties内容如下:

name=JavaChen-dev

application-prod.properties内容如下:

name=JavaChen-prod

接下来进行测试。spring.profiles.active=dev时,运行Application类,查看日志输出。

2016-02-22 15:45:18,470 [main] INFO  com.javachen.example.Application - Hello JavaChen-dev

spring.profiles.active=prod时,运行Application类,查看日志输出。

2016-02-22 15:47:21,270 [main] INFO  com.javachen.example.Application - Hello JavaChen-prod

logback配置多Profile

在resources目录下添加logback-spring.xml,并分别对dev和prod进行配置:

  1.  
    <?xml version="1.0" encoding="UTF-8"?>
  2.  
    <configuration>
  3.  
    <!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->
  4.  
     
  5.  
    <springProfile name="dev">
  6.  
    <logger name="com.javachen.example" level="TRACE" />
  7.  
    <appender name="LOGFILE" class="ch.qos.logback.core.ConsoleAppender">
  8.  
    <encoder>
  9.  
    <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
  10.  
    </encoder>
  11.  
    </appender>
  12.  
    </springProfile>
  13.  
     
  14.  
    <springProfile name="prod">
  15.  
    <appender name="LOGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  16.  
    <File>log/server.log</File>
  17.  
    <rollingPolicy
  18.  
    class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  19.  
    <FileNamePattern>log/server_%d{yyyy-MM-dd}.log.zip</FileNamePattern>
  20.  
    </rollingPolicy>
  21.  
    <layout class="ch.qos.logback.classic.PatternLayout">
  22.  
    <pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
  23.  
    </layout>
  24.  
    </appender>
  25.  
    </springProfile>
  26.  
     
  27.  
    <root level="info">
  28.  
    <appender-ref ref="LOGFILE" />
  29.  
    </root>
  30.  
     
  31.  
    <logger name="com.javachen.example" level="DEBUG" />
  32.  
    </configuration>

这样,就可以做到不同profile场景下的日志输出不一样。

maven中的场景配置

使用maven的resource filter可以实现多场景切换。

  1.  
    <profiles>
  2.  
    <profile>
  3.  
    <id>prod</id>
  4.  
    <activation>
  5.  
    <activeByDefault>true</activeByDefault>
  6.  
    </activation>
  7.  
    <properties>
  8.  
    <build.profile.id>prod</build.profile.id>
  9.  
    </properties>
  10.  
    </profile>
  11.  
    <profile>
  12.  
    <id>dev</id>
  13.  
    <properties>
  14.  
    <build.profile.id>dev</build.profile.id>
  15.  
    </properties>
  16.  
    </profile>
  17.  
    </profiles>
  18.  
     
  19.  
    <build>
  20.  
    <filters>
  21.  
    <filter>application-${build.profile.id}.properties</filter>
  22.  
    </filters>
  23.  
     
  24.  
    <resources>
  25.  
    <resource>
  26.  
    <filtering>true</filtering>
  27.  
    <directory>src/main/resources</directory>
  28.  
    </resource>
  29.  
    </resources>
  30.  
    </build>

这样在maven编译时,可以通过-P参数指定maven profile即可。

总结

使用Spring Boot的Profile注解可以实现多场景下的配置切换,方便开发中进行测试和部署生产环境。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!