浅谈关于spring profile的误解

背景

spring的profile大家都是用的溜的飞起~

那么profile的组合如何使用呢???

比如我们这样使用

@Profile({"prod", "unit-test"})

分析

上述的profile大家应该不会存有疑问 当profile为prod或者unit-test的时候才会生效。

但是如果我们使用非呢~如何确保在某些情况下不生效!

spring提供了常见的!来进行描述

因此如果想要在非生产环境生效只要简单的写成

@Profile({"!prod"})

那么如何在多个环境下不生效呢???

自作聪明的某些人【我】如下代码

@Profile({"!prod", "!unit-test"})

那么实际情况是否如此呢???

我们看一下对应的代码

代码

profile是通过profileCondition来完成控制的

class ProfileCondition implements Condition {

  @Override
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
   if (context.getEnvironment() != null) {
     MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
     if (attrs != null) {
      for (Object value : attrs.get("value")) {
        if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
         return true;
        }
      }
      return false;
     }
   }
   return true;
  }

}

很明显可以看到了acceptsProfiles

/**
 * Return whether one or more of the given profiles is active or, in the case of no
 * explicit active profiles, whether one or more of the given profiles is included in
 * the set of default profiles. If a profile begins with '!' the logic is inverted,
 * i.e. the method will return true if the given profile is <em>not</em> active.
 * For example, <pre class="code">env.acceptsProfiles("p1", "!p2")</pre> will
 * return {@code true} if profile 'p1' is active or 'p2' is not active.
 * @throws IllegalArgumentException if called with zero arguments
 * or if any profile is {@code null}, empty or whitespace-only
 * @see #getActiveProfiles
 * @see #getDefaultProfiles
 */
boolean acceptsProfiles(String... profiles);

从上述可以看到应该是or的条件

当然代码如下

@Override
public boolean acceptsProfiles(String... profiles) {
  Assert.notEmpty(profiles, "Must specify at least one profile");
  for (String profile : profiles) {
   if (StringUtils.hasLength(profile) && profile.charAt(0) == '!') {
     if (!isProfileActive(profile.substring(1))) {
      return true;
     }
   }
   else if (isProfileActive(profile)) {
     return true;
   }
  }
  return false;
}

因此可以看到当是!条件的时候会判断如果当前未激活profile返回true 否则当前是正常条件的换当前profile如果激活则返回true 当上述条件都不满足才返回false

因此上述逻辑告诉我们其实应该是或者的逻辑。因此

@Profile({"!prod", "!unit-test"})

!prod||!unit-test===>!(prod&&unit-test)  也就是说当prod和unit-test都生效的时候才不会注册 其他调均都会注册生效

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Maven管理SpringBoot Profile详解

    1. Spring Profile Spring可使用Profile绝对程序在不同环境下执行情况,包含配置.加载Bean.依赖等. Spring的Profile一般项目包含:dev(开发), test(单元测试), qa(集成测试), prod(生产环境).由spring.profiles.active属性绝定启用的profile. SpringBoot的配置文件默认为 application.properties(或yaml,此外仅心properties配置为说明).不同Profile下的配置

  • spring profile 多环境配置管理详解

     spring profile 多环境配置管理 现象   如果在开发时进行一些数据库测试,希望链接到一个测试的数据库,以避免对开发数据库的影响.   开发时的某些配置比如log4j日志的级别,和生产环境又有所区别.   各种此类的需求,让我希望有一个简单的切换开发环境的好办法. 解决   现在spring3.1也给我们带来了profile,可以方便快速的切换环境.   使用也是非常方便.只要在applicationContext.xml中添加下边的内容,就可以了 <!-- 开发环境配置文件 --

  • 浅谈spring注解之@profile

    spring中@profile与maven中的profile很相似,通过配置来改变参数. 例如在开发环境与生产环境使用不同的参数,可以配置两套配置文件,通过@profile来激活需要的环境,但维护两套配置文件不如maven中维护一套配置文件,在pom中通过profile来修改配置文件的参数来的实惠. 也有例外,比如我在开发中调用商城接口经常不能返回我需要的数据,每次都需要mock数据,所以我写了一个mock参数的借口调用类,在开发环境中就使用这个类,测试环境与生产环境则使用正常的借口调用类,这样

  • Spring Boot的Profile配置详解

    Profile 是Spring Boot用来针对不同的环境对不同的配置提供的支持,全局Profile配置使用application-{profile}.properties,如: application-dev.properties 可以表示为开发环境. 然后通过application.properties文件中的spring.profiles.active=dev来设置 在src/main/resources下面新建 application-dev.properties和application

  • Spring Boot使用profile如何配置不同环境的配置文件

    在springboot的开发中,有时候我们会有不同的配置,例如日志打印,数据库连接等,开发,测试,生产每个环境可能配置都不一致,还好,springboot支持通过不同的profile来配置不同环境的配置,下面就大致介绍一下yml配置文件跟properties配置文件怎么使用profile配置不同环境的配置文件... 先介绍一下开发环境: jdk版本是1.8 springboot的版本是1.4.1 开发工具为 intellij idea 我们先来介绍,使用一个yml文件,通过不同的profile来

  • 详解springboot + profile(不同环境读取不同配置)

    具体做法: 不同环境的配置设置一个配置文件,例如:dev环境下的配置配置在application-dev.properties中:prod环境下的配置配置在application-prod.properties中. 在application.properties中指定使用哪一个文件 1.application-dev.properties(dev环境下的配置) profile = dev_envrimont 2.application-prod.properties(prod环境下的配置) pr

  • spring @profile注解的使用方法

    本文主要介绍spring中@profile的使用方法以及在什么情况下使用. 首先说一下为什么要使用这个@profile注解.@profile注解是spring提供的一个用来标明当前运行环境的注解.我们正常开发的过程中经常遇到的问题是,开发环境是一套环境,qa测试是一套环境,线上部署又是一套环境.这样从开发到测试再到部署,会对程序中的配置修改多次,尤其是从qa到上线这个环节,让qa的也不敢保证改了哪个配置之后能不能在线上运行. 为了解决上面的问题,我们一般会使用一种方法,就是配置文件,然后通过不同

  • Spring入门实战之Profile详解

    前言 Spring中的Profile功能其实早在Spring 3.1的版本就已经出来,它可以理解为我们在Spring容器中所定义的Bean的逻辑组名称,只有当这些Profile被激活的时候,才会将Profile中所对应的Bean注册到Spring容器中. 看到Profile这个关键字,或许你从来没有正眼瞧过他,又或者脑海中有些模糊的印象,比如除了这里Springmvc中的Profile,maven中也有Profile的标签. 从字面意思来看,Profile表示侧面,那什么情况下才会用到侧面这个功

  • 详解Spring Boot Profiles 配置和使用

    介绍 Spring Profiles 提供了一套隔离应用配置的方式,不同的 profiles 提供不同组合的配置,在不同的环境中,应用在启动时通过选择激活某些特定的 profiles 来适应运行时环境,以达到在不同的环境可以使用相同的一套程序代码. 环境 JDK 8 Maven 3 IntelliJ IDEA 2016 Spring Boot 1.5.2.RELEASE @Profiles 你可以在任何 @Component(@Service,@Repository) 或 @Configurat

  • 浅谈关于spring profile的误解

    背景 spring的profile大家都是用的溜的飞起~ 那么profile的组合如何使用呢??? 比如我们这样使用 @Profile({"prod", "unit-test"}) 分析 上述的profile大家应该不会存有疑问 当profile为prod或者unit-test的时候才会生效. 但是如果我们使用非呢~如何确保在某些情况下不生效! spring提供了常见的!来进行描述 因此如果想要在非生产环境生效只要简单的写成 @Profile({"!pro

  • 浅谈一下Spring中的createBean

    目录 找到BeanClass并且加载类 实例化前 实例化 Supplier创建对象 工厂方法创建对象 推断构造方法 BeanDefionition 的后置处理 实例化后 属性填充 Aware回调 初始化前 初始化 初始化后 总结BeanPostProcessor 找到BeanClass并且加载类 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws

  • 浅谈利用Spring的AbstractRoutingDataSource解决多数据源的问题

    在互联网的服务端开发的时候,我们很经常要在一个项目中去调用不同的数据库.在这种情况下,必然要涉及到多数据源问题.那么,我们该如何解决多数据源问题呢?有没有一种方法来动态切换数据源呢? 答案是有的.万能的Spring已经给了我们解决方案--利用AbstractRoutingDataSource.在 AbstractRoutingDataSource 类中,发现 getConnection() 方法,从名字上可以知道它是获得connection连接的.跟踪 getConnection() 方法, d

  • 浅谈升级Spring Cloud到Finchley后的一点坑

    最近为了使用Kotlin以及Webflux进行后台应用开发,把Spring Cloud版本升级到了Finchley. 这种大版本的提升,坑自然是少不了的,我最近会把遇到问题都总结在这里避免大家花太多时间在排坑上: Failed to bind properties under 'eureka.instance.instance-id' to java.lang.String: Description: Failed to bind properties under 'eureka.instanc

  • 浅谈在Spring中如何使用数据源(DBCP、C3P0、JNDI)

    在 Spring 中,有以下三种方式来创建数据源: 通过 JNDI 获取应用服务器中的数据源: 在 Spring 容器中配置数据源: 通过代码来创建数据源,这种方式适用于无容器依赖的单元测试. 1 配置数据源 Spring 在第三方依赖包中包含了 2 种数据源的实现包 一个是 Apache 的 DBCP:另一个是 C3P0. 我们可以在 Spring 配置文件中直接配置这些数据源 . 1.1 DBCP DBCP (Database Connection Pool)是一个依赖 Jakarta co

  • 浅谈Springboot之于Spring的优势

    Spring在Java EE开发中是实际意义上的标准,但我们在开发Spring的时候可能会遇到以下令人头疼的问题: (1)大量配置文件的定义; (2)与第三方软件整合的技术问题,Spring每个新版本的推出都以减少配置作为自己的主要目标,例如: (a)推出@Component, @Service, @Repository, @Controller等注解在类上声明Bean; (b)推出@Configuration, @Bean的Java配置来替代Xml配置. 在脚本语言和敏捷开发大行其道的时代,J

  • 浅谈spring容器中bean的初始化

    当我们在spring容器中添加一个bean时,如果没有指明它的scope属性,则默认是singleton,也就是单例的. 例如先声明一个bean: public class People { private String name; private String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public String get

  • 浅谈Spring的两种事务定义方式

    一.声明式 这种方法不需要对原有的业务做任何修改,通过在XML文件中定义需要拦截方法的匹配即可完成配置,要求是,业务处理中的方法的命名要有规律,比如setXxx,xxxUpdate等等.详细配置如下: <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="

  • 浅谈Spring的两种配置容器

    Spring提供了两种容器类型 SpringIOC容器是一个IOC Service Provider.提供了两种容器类型:BeanFactory和ApplicationContext.Spring的IOC容器是一个提供IOC支持的轻量级容器.除了基本的ioc支持,它作为轻量级容器还提供了IOC之外的支持. BeanFactory BeanFactory是基础类型IOC容器.顾名思义,就是生产Bean的工厂.能够提供完整的IOC服务.没有特殊指定的话,其默认采用延迟初始化策略.只有当客户端对象需要

随机推荐