浅谈关于spring profile的误解
背景
spring的profile大家都是用的溜的飞起~
那么profile的组合如何使用呢???
比如我们这样使用
@Profile({"prod","unit-test"})
分析
上述的profile大家应该不会存有疑问当profile为prod或者unit-test的时候才会生效。
但是如果我们使用非呢~如何确保在某些情况下不生效!
spring提供了常见的!来进行描述
因此如果想要在非生产环境生效只要简单的写成
@Profile({"!prod"})
那么如何在多个环境下不生效呢???
自作聪明的某些人【我】如下代码
@Profile({"!prod","!unit-test"})
那么实际情况是否如此呢???
我们看一下对应的代码
代码
profile是通过profileCondition来完成控制的
classProfileConditionimplementsCondition{ @Override publicbooleanmatches(ConditionContextcontext,AnnotatedTypeMetadatametadata){ if(context.getEnvironment()!=null){ MultiValueMapattrs=metadata.getAllAnnotationAttributes(Profile.class.getName()); if(attrs!=null){ for(Objectvalue:attrs.get("value")){ if(context.getEnvironment().acceptsProfiles(((String[])value))){ returntrue; } } returnfalse; } } returntrue; } }
很明显可以看到了acceptsProfiles
/** *Returnwhetheroneormoreofthegivenprofilesisactiveor,inthecaseofno *explicitactiveprofiles,whetheroneormoreofthegivenprofilesisincludedin *thesetofdefaultprofiles.Ifaprofilebeginswith'!'thelogicisinverted, *i.e.themethodwillreturntrueifthegivenprofileisnotactive. *Forexample,will *return{@codetrue}ifprofile'p1'isactiveor'p2'isnotactive. *@throwsIllegalArgumentExceptionifcalledwithzeroarguments *orifanyprofileis{@codenull},emptyorwhitespace-only *@see#getActiveProfiles *@see#getDefaultProfiles */ booleanacceptsProfiles(String...profiles);env.acceptsProfiles("p1","!p2")
从上述可以看到应该是or的条件
当然代码如下
@Override publicbooleanacceptsProfiles(String...profiles){ Assert.notEmpty(profiles,"Mustspecifyatleastoneprofile"); for(Stringprofile:profiles){ if(StringUtils.hasLength(profile)&&profile.charAt(0)=='!'){ if(!isProfileActive(profile.substring(1))){ returntrue; } } elseif(isProfileActive(profile)){ returntrue; } } returnfalse; }
因此可以看到当是!条件的时候会判断如果当前未激活profile返回true否则当前是正常条件的换当前profile如果激活则返回true当上述条件都不满足才返回false
因此上述逻辑告诉我们其实应该是或者的逻辑。因此
@Profile({"!prod","!unit-test"})
!prod||!unit-test===>!(prod&&unit-test) 也就是说当prod和unit-test都生效的时候才不会注册其他调均都会注册生效
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。