介绍
# Spring注解@Profile实现开发环境,测试环境,生产环境的切换
使用
spring.profiles.active,也可以通过配置jvm参数。
通过Environment设置profile
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(;
context.getEnvironment(.setActiveProfiles("dev";
通过JVM参数设置
可以通过JVM参数来设置环境变量的值,在开发中,这种方式也是使用得比较普遍。
SpringBoot通过yml进行配置
Environment中,这样,spring在后续得流程里面,就能从Environment中获取环境变量,然后进行相应的逻辑处理。
源码解析
BeanDefinition注册
shouldSkip判断,它会筛选出符合的bean,不符合条件的bean则被加入skippedBeanMethods集合中,不会被注册。
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod {
ConfigurationClass configClass = beanMethod.getConfigurationClass(;
MethodMetadata metadata = beanMethod.getMetadata(;
String methodName = metadata.getMethodName(;
// Do we need to mark the bean as skipped by its condition?
if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN {
configClass.skippedBeanMethods.add(methodName;
return;
}
if (configClass.skippedBeanMethods.contains(methodName {
return;
}
}
shouldSkip源码
在shouldSkip中,会使用Condition接口,@Profile使用的是ProfileCondition
,然后调用matches
方法。
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationCondition.ConfigurationPhase phase {
for (Condition condition : conditions {
ConfigurationCondition.ConfigurationPhase requiredPhase = null;
if (condition instanceof ConfigurationCondition configurationCondition {
requiredPhase = configurationCondition.getConfigurationPhase(;
}
if ((requiredPhase == null || requiredPhase == phase && !condition.matches(this.context, metadata {
return true;
}
}
return false;
}
ProfileCondition匹配
在ProfileCondition的matches方法中,主要就是去Environment中寻找环境变量,然后解析@Profile注解设置的value值,如果Environment中激活的配置中包含当前的配置,包含则能为true,不包含则为false,如上通过setActiveProfiles设置Environment中激活的配置为dev,当前传过来的配置为dev,那么就能匹配上,就能装配进IOC容器。
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata {
MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName(;
if (attrs != null {
for (Object value : attrs.get("value" {
if (context.getEnvironment(.acceptsProfiles(Profiles.of((String[] value {
return true;
}
}
return false;
}
return true;
}
从源码可以看出,其最核心的思想就是是否注册bean的元信息BeanDefinition,因为只有注册了BeanDefinition,后续才能为创建bean提供元数据支持,判断是否注册bean元信息,主要就是从Environment中取出profiles的值,然后和@Profile注解设置的值进行匹配,匹配得上就注册,bean不上就不注册。
总结
今天的分享就到这里,感谢你的观看,下期见!