多个否定的配置文件

vul*_*ul6 5 java spring

我的问题是我有应用程序,它使用Spring配置文件.在服务器上构建应用程序意味着配置文件设置为" wo-data-init".对于其他构建,有" test"配置文件.当它们中的任何一个被激活时,它们不应该运行Bean方法,所以我虽然这个注释应该工作:

@Profile({"!test","!wo-data-init"})
Run Code Online (Sandbox Code Playgroud)

它似乎更像是在运行if(!test OR !wo-data-init),在我的情况下我需要它运行if(!test AND !wo-data-init)- 它甚至可能吗?

Jen*_*son 17

在 Spring 5.1.4 (Spring Boot 2.1.2) 及更高版本中,它很简单:

@Component
@Profile("!a & !b")
public class MyComponent {}
Run Code Online (Sandbox Code Playgroud)

参考:当多个配置文件未处于活动状态时,如何有条件地声明 Bean?


Mac*_*iak 9

Spring 4为条件bean创建带来了一些很酷的功能.在您的情况下,确实简单的@Profile注释是不够的,因为它使用OR运算符.

您可以执行的解决方案之一是为其创建自定义注释和自定义条件.例如

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional(NoProfilesEnabledCondition.class)
public @interface NoProfilesEnabled {
    String[] value();
}
Run Code Online (Sandbox Code Playgroud)
public class NoProfilesEnabledCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        boolean matches = true;

        if (context.getEnvironment() != null) {
            MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(NoProfileEnabled.class.getName());
            if (attrs != null) {
                for (Object value : attrs.get("value")) {
                    String[] requiredProfiles = (String[]) value;

                    for (String profile : requiredProfiles) {
                        if (context.getEnvironment().acceptsProfiles(profile)) {
                            matches = false;
                        }
                    }

                }
            }
        }
        return matches;
    }
}
Run Code Online (Sandbox Code Playgroud)

以上是快速和肮脏的修改ProfileCondition.

现在您可以通过以下方式注释bean:

@Component
@NoProfilesEnabled({"foo", "bar"})
class ProjectRepositoryImpl implements ProjectRepository { ... }
Run Code Online (Sandbox Code Playgroud)