http://blog.csdn.net/he90227/article/details/52981747
摘要: spring Boot使用@Profile注解可以實現不同環境下配置參數的切換,任何@Component或@Configuration注解的類都可以使用@Profile注解。 例如: @Configuration @Profile("production") public class Produc...
Spring Boot使用@Profile注解可以實現不同環境下配置參數的切換,任何@Component或@Configuration注解的類都可以使用@Profile注解。
例如:
@Configuration @Profile("production") public class ProductionConfiguration { // ... }
通常,一個項目中可能會有多個profile場景,例如下面為test場景:
@Configuration @Profile("test") public class TestConfiguration { // ... }
在存在多個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注解支持定義在其他注解之上,以創建自定義場景注解。
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Profile("dev") public @interface Dev { }
這樣就創建了一個@Dev注解,該注解可以標識bean使用於@Dev這個場景。后續就不再需要使用@Profile("dev")的方式。這樣即可以簡化代碼,同時可以利用IDE的自動補全:)
多個Profile例子
下面是一個例子:
package com.javachen.example.service; public interface MessageService { String getMessage(); }
對於MessageService接口,我們可以有生產和測試兩種實現:
package com.javachen.example.service; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; @Component @Profile({ "dev" }) public class HelloWorldService implements MessageService{ @Value("${name:World}") private String name; public String getMessage() { return "Hello " + this.name; } }
package com.javachen.example.service; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; @Component @Profile({ "prod" }) public class GenericService implements MessageService { @Value("${hello:Hello}") private String hello; @Value("${name:World}") private String name; @Override public String getMessage() { return this.hello + " " + this.name; } }
Application類為:
@SpringBootApplication public class Application implements CommandLineRunner { private static final Logger logger = LoggerFactory.getLogger(Application.class); @Autowired private MessageService messageService; @Override public void run(String... args) { logger.info(this.messageService.getMessage()); if (args.length > 0 && args[0].equals("exitcode")) { throw new ExitException(); } } public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } }
實際使用中,使用哪個profile由spring.profiles.active控制,你在resources/application.properties中定義spring.profiles.active=XXX,或者通過-Dspring.profiles.active=XXX。XXX可以是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進行配置:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!--<include resource="org/springframework/boot/logging/logback/base.xml" />--> <springProfile name="dev"> <logger name="com.javachen.example" level="TRACE" /> <appender name="LOGFILE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> </springProfile> <springProfile name="prod"> <appender name="LOGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>log/server.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>log/server_%d{yyyy-MM-dd}.log.zip</FileNamePattern> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern> </layout> </appender> </springProfile> <root level="info"> <appender-ref ref="LOGFILE" /> </root> <logger name="com.javachen.example" level="DEBUG" /> </configuration>
這樣,就可以做到不同profile場景下的日志輸出不一樣。
maven中的場景配置
使用maven的resource filter可以實現多場景切換。
<profiles> <profile> <id>prod</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <build.profile.id>prod</build.profile.id> </properties> </profile> <profile> <id>dev</id> <properties> <build.profile.id>dev</build.profile.id> </properties> </profile> </profiles> <build> <filters> <filter>application-${build.profile.id}.properties</filter> </filters> <resources> <resource> <filtering>true</filtering> <directory>src/main/resources</directory> </resource> </resources> </build>
這樣在maven編譯時,可以通過-P參數指定maven profile即可。
總結
使用Spring Boot的Profile注解可以實現多場景下的配置切換,方便開發中進行測試和部署生產環境。
本文中相關代碼在github上面。
