[关闭]
@babydragon 2015-11-13T14:12:29.000000Z 字数 2664 阅读 2160

spring boot profile试用

博客


项目中需要在不同环境切换,之前类似的需求,主要在于一些配置的不同,如数据库配置等。这样的场景,通过maven的profile,结合resource filter即可。但是这次需要针对不同的场景,使用不同的实现类,以此来对接外部不同的系统。

本文基本上参考了spring博客中的介绍,通过@profile注解,来区分不同的使用场景。

自定义场景注解

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

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

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

配置类场景控制

有了上面定义的注解,可以直接在有@Configure注解的配置类上的增加,以控制该类创建的Bean,只在指定场景下激活。例如:

  1. @Configuration
  2. @Cloud
  3. public class CloudWebFilterConfig {
  4. private static final String FROM = "aliyun";
  5. @Bean
  6. public Filter ssoFilter() {
  7. return new SSOFilter();
  8. }
  9. @Bean
  10. public FilterRegistrationBean ssoFilterRegistrationBean() {
  11. FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
  12. filterRegistrationBean.setFilter(ssoFilter());
  13. filterRegistrationBean.setName("ssoFilter");
  14. filterRegistrationBean.setUrlPatterns(Collections.singletonList("/*"));
  15. filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
  16. return filterRegistrationBean;
  17. }
  18. }

上面的配置类,创建了两个bean,其中一个是springboot使用的filter,使用我们针对云上单点登录的实现;另一个是这个filter的配置,配置了这个filter的路径和名称,还有顺序。这里的配置和直接在web.xml中配置filter类似。唯一不同的是,FilterRegistrationBean支持设置filter的优先级。

基于service实现的场景控制

除了上述通过配置类的方式控制之外,@Profile和自定义的(@Cloud)注解还可以直接应用的@Service@Component等注解创建的服务实现上。同样,带上场景注解之后,这些服务实现只会在场景激活之后才会实例化。

例如,我们可以定义一个用户查询接口:

  1. public interface UserService {
  2. List<AegisUser> fuzzyQuery(String query);
  3. }

在不同场景下,我们需要有不同的实现。

  1. @Service
  2. @Cloud
  3. public class UserServiceAImpl implements UserService {
  4. public List<AegisUser> fuzzyQuery(String query) {
  5. ...
  6. }
  7. }
  1. @Service
  2. @Cloud
  3. public class UserServiceBImpl implements UserService {
  4. public List<AegisUser> fuzzyQuery(String query) {
  5. ...
  6. }
  7. }

上面创建了两个UserService的实现,一个标记为内部使用,一个标记为云上使用。

这样,对于上层平台,只需要直接@Autowired注解注入即可,无须再通过@Qualifier注解指定具体的实现了。运行时注入,会通过场景指定具体的实现类。

场景切换配置

spring boot在启动时需要指定当前激活的场景,主要方式有两个:

  1. 命令行参数指定:启动时,直接在命令行参数中增加:spring.profiles.active=cloud参数
  2. 在properties文件中指定,在应用依赖的properties文件中增加spring.profiles.active=cloud等配置,即可切换场景

为了能够在打包的时候就确定启动场景,最终还是采用了后者,并且和maven的resource filter结合。即在properties文件中使用占位符,在maven的profile中通过filter,通过maven profile来编译时替换。

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

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

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注