欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring中@Profile的妙用

程序员文章站 2022-07-12 11:14:49
...

       最近项目中需要开发一个定时任务,项目中已经落地spring cloud微服务框架,schedule task server作为一个独立服务部署,但是业务层逻辑代码又包含在主服务的一个module中,在开发阶段启动过多的服务与开发调试不便,于是想着将定时任务集成到主服务中便于调试(类似Unit Test),但是在生产环境中又要保证这个定时任务不会在主服务中启动,此时@Profile 闪亮登场。

 

@Profile("dev")
@Component
public class TestTask {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Scheduled(cron = "*/10 * * * * ?")
    public void testJob() {
        log.debug("****************start*****************");
        // do something......
        log.debug("*****************end *****************");
    }
}

  

 

       使用过SpringBoot的朋友应该知道,spring boot能在运行时自动为我们选择不同的profile环境配置,例如,dev环境,test测试环境,prd生产环境的各个数据库用户名,密码等都不相同,spring boot的服务启动时会根据我们指定的profile选择对应的配置,省去我们手动更改或执行脚本更改的步骤。这里@Profile({"dev")的意思是当指定的profile=dev时,@Component注解将会生效,TestTask对象将会被注册到Spring的bean工厂中去,定时任务会被执行,相反,如果指定的profile不为dev,@Component注解会失效,注册动作将不会发生。

 

接下来查看@Profile的定义:

 

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({ProfileCondition.class})
public @interface Profile {
    String[] value();
}

 

    了解注解的朋友会注意到 String[] value(); value是一个数组? 没错,@Profile可以指定多个环境的profile,例如 @Profile({"dev", "test"})表示此任务将会在profile为dev或test环境中被执行。另外,value支持取反 "!" 运算符操作,@Profile("!dev")表示代码将在profile不为dev的环境中生效。

 

    相信读者已经能对@Profile的妙用有所体会,最后再提醒大家注意的一点是,当指定多个profile时,各个profile之间是 “or” 条件生效,例如@Profile({"dev", "!test"})表示代码将在profile=dev或者profile!=test时生效,另外当前不支持多个profile之间的 与 操作,对此有疑问的朋友可以google "AndProfilesCondition"类,许多人对“多个prifile不支持与操作”的问题耿耿于怀,在Stack Overflow上还能见到其他网友对这个类的代码实现。