2014-05-07 5 views
7

Ich habe eine Spring Klasse, die eine Bean registrieren sollte, wenn ein bestimmter Eigenschaftswert in der Umgebung festgelegt ist. Ich schrieb eine benutzerdefinierte Condition Implementierung, die überprüft, ob der Wert vorhanden war, und es funktioniert, wenn ich die Anwendung in Spring Boot hochfährt, aber die Bohne wurde nie registriert, wenn JUnit Tests ausgeführt. Ich debuggte die Anwendung und stellte fest, dass die Condition ausgewertet wurde, bevor die PropertySourcesPlaceholderConfigurer instanziiert wurde.Wie verzögere ich die Auswertung einer Spring @ Conditional-Konfigurationsannotation?

Ich habe meine Condition geändert, um ConfigurationCondition zu implementieren und die Auswertung während der REGISTER_BEAN Phase zu spezifizieren. Die Methode wird immer noch aufgerufen, bevor der Konfigurator instanziiert wird, aber die registrierte Bean kommt und geht, wenn ich die Eigenschaft aus der Eigenschaftendatei hinzufüge oder entferne.

Ist dies der beste Weg, die Auswertung neu zu ordnen? Ist das, was die ConfigurationCondition Schnittstelle ist, oder bin ich nur versehentlich es jetzt zu arbeiten?

@Conditional(PropertyCondition.class) 
@Configuration 
public class PostbackUrlConfiguration { 
    @Value("${serviceName.postbackUrl}") 
    String postbackUrl; 

    @Bean 
    public PostbackUrlProvider provider() { 
     return new FixedUrlProvider(postbackUrl); 
    } 
} 

 

public class PropertyCondition implements ConfigurationCondition { 
    @Override 
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 
     return context.getEnvironment().containsProperty("serviceName.postbackUrl"); 
    } 

    @Override 
    public ConfigurationPhase getConfigurationPhase() { 
     return ConfigurationPhase.REGISTER_BEAN; 
    } 
} 

Die Testkonfiguration ist eine statische Klasse auf meinem Testfall:

@Configuration 
@ComponentScan 
@PropertySource("classpath:/postback.properties") 
@Import(PostbackUrlConfiguration.class) 
public static class TestConfig { 
    @Bean 
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 
     return new PropertySourcesPlaceholderConfigurer(); 
    } 
} 
+0

Verwenden Sie eine @ Configuration- und eine @ Bean-Annotation, um Ihren PropertySourcesPlaceholderConfigurer in Ihrem JUnit-Test zu deklarieren? –

+0

@ Jean-PhilippeBond Ja, und der PSPC ist "statisch" gemäß einer Anforderung, die ich speziell für diese Art von Komponente sah. Vollständige Test-Config-Klasse veröffentlicht. – chrylis

Antwort

8

Die parsing phase für eine @Configuration Klasse beinhaltet reading its class definition, populating a collection of Configuration objects (because one @Configuration class may @Import another @Configuration class so these imports are parsed as well), processing @PropertySources, @ImportResources etc.

Verarbeitung @PropertySources lädt auch diese Eigenschaften noch nicht. Nachdem die Analysephase abgeschlossen ist, werden die Eigenschaften @PropertySources geladen. Nachdem diese geladen wurden, werden die Definitionen der Beans aus den Klassen registriert (Phase REGISTER_BEAN).

Also, was Sie ein ConfigurationCondition mit ConfigurationPhase.REGISTER_BEAN Phase siehe unter Verwendung erwartet wird, weil diese Eigenschaften in den Environment zur Zeit tatsächlich verfügbar sind, wenn Bohnen Definitionen registriert sind und nach der @Configuration Klasse analysiert wurde. Mit nur einem Condition glaube ich, es erreicht nicht einmal die Parsing-Phase von , die Auswertung erfolgt schon davor, wenn die Klassendefinition registriert werden soll.

Verwandte Themen