我可以否定(!)一系列弹簧型材吗?

Hel*_*eat 13 java spring config spring-boot

是否可以以一种不被一组配置文件使用的方式配置bean?目前我可以这样做(我相信):

@Profile("!dev, !qa, !local")
Run Code Online (Sandbox Code Playgroud)

是否有更简洁的符号来实现这一目标?我们假设我有很多个人资料.另外,如果我有一个Mock和一些服务(或其他)的具体实现,我可以只注释其中一个,并假设另一个将用于所有其他情况?换句话说,这是必要的:

@Profile("dev, prof1, prof2")
public class MockImp implements MyInterface {...}

@Profile("!dev, !prof1, !prof2") //assume for argument sake that there are many other profiles
public class RealImp implements MyInterface {...}
Run Code Online (Sandbox Code Playgroud)

我可以只注释其中一个,并@Primary在另一个上添加注释吗?

本质上我想要这个:

@Profile("!(dev, prof1, prof2)")
Run Code Online (Sandbox Code Playgroud)

提前致谢!

小智 35

从 Spring 5.1(包含在 Spring Boot 2.1 中)开始,可以在配置文件字符串注释中使用配置文件表达式有关详细信息,请参阅Profile.of(..)中的描述)。

因此,要从某些配置文件中排除您的 bean,您可以使用这样的表达式:

@Profile("!dev & !prof1 & !prof2")
Run Code Online (Sandbox Code Playgroud)

也可以使用其他逻辑运算符,例如:

@Profile("test | local")
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的评论,用最新的信息更新旧帖子真是令人钦佩。 (3认同)

Ant*_*ond 16

简短的回答是:你做不到.
但是由于@Conditional注释,存在整齐的变通方法.

创建条件匹配器:

public abstract class ProfileCondition extends SpringBootCondition {
    @Override
    public ConditionOutcome getMatchOutcome(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        if (matchProfiles(conditionContext.getEnvironment())) {
            return ConditionOutcome.match("A local profile has been found.");
        }
        return ConditionOutcome.noMatch("No local profiles found.");
    }

    protected abstract boolean matchProfiles(final Environment environment);
}

public class DevProfileCondition extends ProfileCondition {
   private boolean matchProfiles(final Environment environment) {    
        return Arrays.stream(environment.getActiveProfiles()).anyMatch(prof -> {
            return prof.equals("dev") || prof.equals("prof1")) || prof.equals("prof2"));
        });
    }
}

public class ProdProfileCondition extends ProfileCondition {
   private boolean matchProfiles(final Environment environment) {    
        return Arrays.stream(environment.getActiveProfiles()).anyMatch(prof -> {
            return !prof.equals("dev") && !prof.equals("prof1")) && !prof.equals("prof2"));
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

用它

@Conditional(value = {DevProfileCondition.class})
public class MockImpl implements MyInterface {...}

@Conditional(value = {ProdProfileCondition.class})
public class RealImp implements MyInterface {...}
Run Code Online (Sandbox Code Playgroud)

但是,这种方法需要Springboot.