2011-01-15 1 views
19

I @Value Anmerkung in den Parametern eines Konstruktor zu verwenden, versuchen wie folgt:Frühling @Value Annotation nicht standardmäßig verwenden, wenn Eigenschaft nicht vorhanden ist

@Autowired 
public StringEncryptor(
    @Value("${encryptor.password:\"\"}") String password, 
    @Value("${encryptor.algorithm:\"PBEWithMD5AndTripleDES\"}") String algorithm, 
    @Value("${encryptor.poolSize:10}") Integer poolSize, 
    @Value("${encryptor.salt:\"\"}") String salt) { 
... 
} 

Wenn die Eigenschaftsdatei auf dem Classpath vorhanden ist, die Eigenschaften werden perfekt geladen und der Test wird ordnungsgemäß ausgeführt. Wenn ich jedoch die Eigenschaftendatei aus dem Klassenpfad lösche, hätte ich erwartet, dass die Standardwerte verwendet worden wären, zum Beispiel poolSize würde auf 10 oder Algorithmus auf PBEWithMD5AndTripleDES gesetzt werden, dies ist jedoch nicht der Fall.

Ausführen des Codes durch einen Debugger (die erst nach @Value("${encryptor.poolSize:10}") Integer poolSize zu @Value("${encryptor.poolSize:10}") String poolSize Wechsel funktionieren würde, wie es NumberFormatExceptions verursacht wurde) Ich finde, dass die Standardeinstellungen nicht festgelegt werden und die Parameter in Form von:

poolSize = ${encryptor.poolSize:10} oder

algorithm = ${encryptor.algorithm:"PBEWithMD5AndTripleDES"} 

statt der erwarteten

poolSize = 10 oder

algorithm = "PBEWithMD5AndTripleDES" 

Basierend auf SPR-4785 sollte die Notation wie $ {my.property:myDefaultValue} funktionieren. Aber es passiert nicht für mich!

Danke

Antwort

22

Vielleicht Initialisierung der Eigenschaft Platzhalter configurer nicht wegen verpasster Properties-Datei, so dass Platzhalter nicht aufgelöst werden. Sie können es so konfigurieren, verpassten Dateien zu ignorieren wie folgt (wenn Sie context Namespace verwenden, es zu konfigurieren):

<context:property-placeholder ignore-resource-not-found="true" ... /> 

Sie auch nicht "..." Werte um Standard brauchen.

+0

Genau das, was ich fehlte. Vielen Dank! – garyj

+0

... oder wenn eine Annotation-basierte Konfiguration mit einem 'PropertySourcePlaceholderConfigurer' verwendet wird:' propertySourcesPlaceholderConfigurer.setIgnoreResourceNotFound (true); ' –

6

ignore-resource-not-found = "true" ist nicht notwendig, damit die Standardwerte übernommen werden. Der Standardwert für den Standardwert ist, dass er verwendet wird, wenn die Eigenschaft nirgendwo gefunden wird.

Ich denke der letzte Satz in der vorherigen Antwort verweist auf das Problem - falsche EL, die Sie ursprünglich bereitgestellt haben müssen, aber dann aus dem Beispiel entfernt. Die Tatsache, dass Sie Formatkonvertierungsausnahmen erhielten, weist ebenfalls darauf hin. Normalerweise konvertiert Spring Strings automatisch in den entsprechenden "Standard" - Java-Typ und, sofern Sie Ihre eigene Implementierung des Spring Conversion Service bereitstellen, auch auf Ihre benutzerdefinierten Objekte - sofern Ihr Konvertierungsdienst im App-Kontext definiert ist.

"ignore-resource-not-found" ist nützlich, wenn Sie Eigenschaften über XML ohne Standardwerte injizieren und nicht möchten, dass der Container eine Ausnahme auslöst, wenn die Bean nicht gefunden wird. In solchen Fällen werden die Bean-Eigenschaften mit den Java-Standardeinstellungen initialisiert, z. Nullen für Objekte, Nullen für primitive numerische Werte usw.

2

In meinem Fall funktionierte das Auflösen der Eigenschaftswerte (und der Standardwerte) nicht im Test, wo ich eine Annotation-basierte Konfiguration verwende. Es stellte sich heraus, dass ich eine PropertySourcesPlaceholderConfigurer hinzufügen musste, damit Eigenschaften tatsächlich aufgelöst werden. Es wurde in der PropertySource Annotation JavaDoc erläutert:

Um $ {...} Platzhalter in Definitionen oder @ Value-Annotationen mit Eigenschaften aus einer PropertySource, muss man einen PropertySourcesPlaceholderConfigurer registrieren. Dies geschieht automatisch bei der Verwendung in XML, muss jedoch explizit mit einer statischen @Bean-Methode registriert werden, wenn @Configuration-Klassen verwendet werden. Weitere Informationen und Beispiele finden Sie im Abschnitt "Mit externalisierten Werten arbeiten" in @Configuration Javadoc und "eine Anmerkung zu BeanFactoryPostProcessor - @Bean-Methoden zurückgeben" von @Bean Javadoc.

Nachfolgend hat der Trick:

@Bean 
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 
    return new PropertySourcesPlaceholderConfigurer(); 
} 

Und wenn Sie einzelne Eigenschaften hinzufügen möchten:

@Bean 
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 

    PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); 

    Properties properties = new Properties(); 
    properties.put("batchSize", "250"); 
    propertySourcesPlaceholderConfigurer.setProperties(properties); 

    return propertySourcesPlaceholderConfigurer; 
}