2015-10-26 7 views
15

Ho seguente file di configurazione:primavera @Configuration con PropertyPlaceholderConfigurer fagioli non risolve annotazione @Value

@Configuration 
public class PropertyPlaceholderConfigurerConfig { 

    @Value("${property:defaultValue}") 
    private String property; 

    @Bean 
    public static PropertyPlaceholderConfigurer ppc() throws IOException { 
     PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); 
     ppc.setLocations(new ClassPathResource("properties/" + property + ".properties")); 
     ppc.setIgnoreUnresolvablePlaceholders(true); 
     return ppc; 
    } 
} 

corro la mia applicazione con seguente opzione VM:

-Dproperty=propertyValue 

quindi mi piacerebbe come la mia applicazione per caricare un file di proprietà specifico all'avvio. Ma per qualche ragione in questa fase le annotazioni non vengono elaborate e la proprietà è null. D'altra parte se ho configurato tramite file xml - tutto funziona perfettamente come previsto. esempio di file XML:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="ignoreResourceNotFound" value="true"/> 
    <property name="location"> 
     <value>classpath:properties/${property:defaultValue}.properties</value> 
    </property> 
</bean> 

Se provo a iniettare valore della proprietà in un altro file di configurazione primavera - sia correttamente iniettato. Se trasferisco la mia creazione di bean PropertyPlaceholderConfigurer a quel file di configurazione, il valore del campo è di nuovo nullo.

Come soluzione alternativa, io uso questa riga di codice:

System.getProperties().getProperty("property", "defaultValue") 

che è anche funziona, ma mi piacerebbe sapere perché tale comportamento è si verifica e forse è possibile riscrivere in altro modo, ma senza xml?

+1

Innanzitutto suggerisco fortemente l'uso di 'ProperySourcesPlaceholderConfigurer' e uso un' @ PropertySource' sulla classe. Secondo, il bean deve essere 'static'. –

+0

@ M.Deinum '@ PropertySource' funziona perfettamente per me, ma cosa succede se ho un'implementazione personalizzata di' ProperySourcesPlaceholderConfigurer'? –

+0

Perché avresti bisogno di un'implementazione personalizzata. –

risposta

30

Dalla primavera JavaDoc:

Al fine di risolvere $ {...} segnaposto nelle definizioni o annotazioni @value utilizzando oggetti di un PropertySource, si deve registrare un PropertySourcesPlaceholderConfigurer. Ciò accade automaticamente quando si utilizza in XML, ma deve essere registrato esplicitamente usando un metodo @Bean statico quando si usano le classi @Configuration. Vedi la sezione "Lavorare con valori esterni" di javadoc di @ Configuration e "una nota sui metodi BeanFactoryPostProcessor-return @Bean" di javadoc di @ Bean per dettagli ed esempi.

Quindi, si sta tentando di utilizzare un segnaposto nel blocco di codice richiesto per abilitare l'elaborazione segnaposto.

Come menzionato @ M.Deinum, è necessario utilizzare un PropertySource (implementazione predefinita o personalizzata).

L'esempio seguente mostra come utilizzare le proprietà in un'annotazione PropertySource e come inserire proprietà da PropertySource in un campo.

@Configuration 
@PropertySource(
      value={"classpath:properties/${property:defaultValue}.properties"}, 
      ignoreResourceNotFound = true) 
public class ConfigExample { 

    @Value("${propertyNameFromFile:defaultValue}") 
    String propertyToBeInjected; 

    /** 
    * Property placeholder configurer needed to process @Value annotations 
    */ 
    @Bean 
    public static PropertySourcesPlaceholderConfigurer propertyConfigurer() { 
     return new PropertySourcesPlaceholderConfigurer(); 
    } 
} 
2

Se si esegue l'applicazione utilizzando l'opzione VM e poi si desidera accedere all'opzione nell'applicazione quello che dovete fare è leggermente diverso:

@Value("#{systemProperties.property}") 
private String property; 

tuo PropertyPlaceholderConfigurer non è a conoscenza di proprietà di sistema, si noti anche che si stanno accedendo alle proprietà usando $ - che si riferisce ai segnaposto e # si riferisce ai fagioli, dove systemProperties è un bean.

+0

Sfortunatamente non funziona nella configurazione in cui ho la creazione di bean PropertyPlaceholderConfigurer, ma funziona in qualsiasi un altro file di configurazione –

3

Per tutte le altre povere anime che non hanno potuto ottenere questo a lavorare in alcune classi di configurazione quando lavorano negli altri:

guardare per vedere quali altri fagioli che avete in quella classe e se qualcuno di loro ottenere istanziato all'inizio del ApplicationContext. Un servizio di conversione è un esempio di uno.Ciò istanzia la classe Configuration prima che sia registrato ciò che è richiesto, quindi non avviene alcuna iniezione di proprietà.

Ho risolto questo problema spostando il ConversionService in un'altra classe di configurazione che ho importato.