spring boot profile试用

spring boot profile试用

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

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

自定义场景注解

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

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

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

配置类场景控制

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

@Configuration
@Cloud
public class CloudWebFilterConfig {

    private static final String FROM = "aliyun";

    @Bean
    public Filter ssoFilter() {
        return new SSOFilter();
    }

    @Bean
    public FilterRegistrationBean ssoFilterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(ssoFilter());
        filterRegistrationBean.setName("ssoFilter");
        filterRegistrationBean.setUrlPatterns(Collections.singletonList("/*"));

        filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);

        return filterRegistrationBean;
    }
}

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

基于service实现的场景控制

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

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

public interface UserService {
    List<AegisUser> fuzzyQuery(String query);
}

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

@Service
@Cloud
public class UserServiceAImpl implements UserService {
    public List<AegisUser> fuzzyQuery(String query) {
        ...
    }
}
@Service
@Cloud
public class UserServiceBImpl implements UserService {
    public List<AegisUser> fuzzyQuery(String query) {
        ...
    }
}

上面创建了两个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来编译时替换。

<profiles>
    <profile>
        <id>internal</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <build.profile.id>internal</build.profile.id>
        </properties>
    </profile>
    <profile>
        <id>cloud</id>
        <properties>
            <build.profile.id>cloud</build.profile.id>
        </properties>
    </profile>
</profiles>

<build>
        <filters>
            <filter>profiles/${build.profile.id}/config.properties</filter>
        </filters>

        <resources>
            <resource>
                <filtering>true</filtering>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
        ...
</build>    

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

发表评论

电子邮件地址不会被公开。 必填项已用*标注