Spring中@Profile的妙用

阅读更多

       最近项目中需要开发一个定时任务,项目中已经落地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上还能见到其他网友对这个类的代码实现。

 

 

 

 

你可能感兴趣的:(Spring,@Profile,java,spring,boot)