2016-12-09 1 views
1

Мы построили Spring загрузочного стартера, который описывает его конфигурация в классе с аннотацией @ConfigurationProperties:Не удается проверить отсутствие имущества, если объявлен в @ConfigurationProperty

@ConfigurationProperties(name = "foo.bar") 
public class FooConfiguration { 
    public String baz; 
} 

Вне стартера Я хочу, чтобы выполнить какое-либо действие в зависимости от являются ли свойство не набора с использованием @ConditionalOnProperty аннотации:

@Bean 
@ConditionalOnProperty(name = "foo.bar.baz", matchIfMissing=true) 
public FooReplacement moo() { 
    return new FooReplacement(); 
} 

Однако это условие никогда не совпадает, если свойство foo.bar.baz описывается в классе Annot с помощью @ConditionProperties. Если он не описан в таком классе, аннотация @ConditionalOnProperty работает просто отлично.

Мы используем Spring бутса 1.4

Итак, это путь Spring загрузка должна работать или мы заметили ошибку?

+0

Вы имели в виду '@ ConfigurationProperties', когда вы писали' @ ConditionProperties' –

+0

я написал модульное тестирование, что я думаю, что упражнения ваш сценарий, но я не был в состоянии воспроизвести вашу неудачу. Я использую выпуск 1.4.1 SpringBoot, попробуйте обновить его в качестве потенциального решения. Я отправлю блок-тест, если вы этого захотите. –

+0

@BobLukens да, единичный тест будет приветствоваться. :) и да, в абзаце ниже второй фрагмент кода я имел в виду ConfigurationProperties вместо ConditionProperties. ;) – roborob

ответ

1

Вот тест блок я соединял, что я считаю, захватить ваш сценарий, но я не смог воссоздать сбой. Вы можете просмотреть и определить, являются ли они разными или неправильными. Я использую Spring Boot 1.4.1. Надеюсь, это поможет вам преодолеть проблему.

package com.sbp; 

import static org.junit.Assert.assertEquals; 
import static org.junit.Assert.assertFalse; 
import static org.junit.Assert.assertNull; 
import static org.junit.Assert.assertTrue; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 
import org.springframework.boot.context.properties.ConfigurationProperties; 
import org.springframework.boot.context.properties.EnableConfigurationProperties; 
import org.springframework.boot.test.context.SpringBootTest; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.env.Environment; 
import org.springframework.stereotype.Component; 
import org.springframework.test.context.junit4.SpringRunner; 

@RunWith(SpringRunner.class) 
@SpringBootTest(classes = PropsTest.TestContext.class) 
public class PropsTest { 

    @Configuration 
    @EnableConfigurationProperties // needed since im not loading a class annotated with @SpringBootApplication 
    public static class TestContext { 

     // this exists in properties file (im using application.yaml) with value = moo 
     // foo.bar.baz: moo 
     @Component 
     @ConfigurationProperties(exceptionIfInvalid = true, value = "foo.bar") 
     public static class FooConfiguration { 
      private String baz; 

      public String getBaz() { 
       return baz; 
      } 

      public void setBaz(String baz) { 
       this.baz = baz; 
      } 
     } 

     // this property doesn't exist in properties file 
     @Component 
     @ConfigurationProperties(exceptionIfInvalid = true, value = "foo.bar1") 
     public static class Foo1Configuration { 
      private String baz; 

      public String getBaz() { 
       return baz; 
      } 

      public void setBaz(String baz) { 
       this.baz = baz; 
      } 
     } 

     @Bean 
     @ConditionalOnProperty(name = "foo.bar.baz", matchIfMissing = false, havingValue = "moo") 
     public FooReplacement moo() { 
      return new FooReplacement(); 
     } 

     @Bean 
     @ConditionalOnProperty(name = "foo.bar.baz", matchIfMissing = false, havingValue = "noo") 
     public FooReplacement noo() { 
      return new FooReplacement(); 
     } 

     // i think this is your scenario 
     @Bean 
     @ConditionalOnProperty(name = "foo.bar1.baz", matchIfMissing = true) 
     public FooReplacement ooo() { 
      return new FooReplacement(); 
     } 

     @Bean 
     @ConditionalOnProperty(name = "foo.bar1.baz", matchIfMissing = false) 
     public FooReplacement qoo() { 
      return new FooReplacement(); 
     } 
    } 

    public static class FooReplacement { 
    } 

    @Autowired 
    private ApplicationContext ctx; 

    @Autowired 
    private TestContext.FooConfiguration fooConfiguration; 

    @Autowired 
    private TestContext.Foo1Configuration foo1Configuration; 

    @Autowired 
    private Environment environment; 

    @Test 
    public void propertyNotDefined_shouldCreateBean() { 
     assertTrue(ctx.containsBean("moo")); 
     assertFalse(ctx.containsBean("noo")); 
     assertTrue(ctx.containsBean("ooo")); 
     assertFalse(ctx.containsBean("qoo")); 

     assertNull(environment.getProperty("foo.bar1.baz", String.class)); 
     assertEquals("moo", environment.getProperty("foo.bar.baz", String.class)); 

     assertNull(foo1Configuration.baz); 
     assertEquals("moo", fooConfiguration.baz); 
    } 
} 
+0

Спасибо за полезную пробную версию! К сожалению, на моей машине (MacOS Sierra, JDK 1.8.102) уже первое утверждение не удалось. Я поделился тестом как с целым проектом на Github: https://github.com/rjayasinghe/spring-conditional-test – roborob

+0

глупо мне забыл создать сопоставление файлов свойств с вашими комментариями в тестовом файле. ;) теперь он работает так, как ожидалось. :) – roborob

+0

добавьте это в свой файл application.properties: 'foo.bar.baz = moo'. тест проходит через 4 сценария - 1. условно создает bean-компонент, когда свойство определяется с соответствующим значением, 2. условно создает bean-компонент, когда свойство определено, но значение не соответствует 3. условно создает bean-компонент, когда свойство не определено 4. условно Не создавайте компонент, когда свойство не определено –

0

Существует проблема уже сообщалось в весеннем проекте, вы извлекаете обсуждение https://github.com/spring-projects/spring-boot/issues/2282

+0

отлично. этот отчет об ошибке подтверждает мое предположение. :) – roborob

+0

, хотя они сообщают о противоположном поведении того, что я наблюдаю, - это дает мне хорошее представление. ;) – roborob

Смежные вопросы