2016-05-01 46 views
11

sto cercando di migrare un'applicazione play framework da 2,4 a 2.5.3 e non ho problemi a ottenere i valori da application.conf di file:Giocare 2.5.3: Utilizzando l'iniezione di dipendenza per ottenere la configurazione valori

Prima per ottenere un valore da application.conf quello che faccio è:

Play.application().configuration().getString("label") 

Ora come Play.application() è deprecato, dovrei usare l'iniezione di dipendenza. Sulla base del framework documentation io uso le seguenti istruzioni:

  1. Definire importazione: import javax.inject.*; import play.Configuration;
  2. Definire proprietà di classe: @Inject private Configuration configuration;
  3. Utilizzare la proprietà classe di configurazione sulla mia classe

Quando seguo queste istruzioni sul mio controller Application.java funziona perfettamente:

Ma quando provo ad usarlo su un altro oggetto di classe dal mio progetto, l'iniezione di dipendenza non funziona e ottengo sempre un NullPointerException.

Qualcuno può darmi un esempio su come ottenere valori da application.conf usando Injection dipendenza?

Una parte del mio codice Java in cui cerco di usare il DI:

import javax.inject.Inject; 
import play.Configuration; 
import play.Logger; 

public class Zipper { 

    @Inject private Configuration configuration; 

    public void unZip(String zipFilePath) { 
     Logger.debug("Display : zipFilePath"+zipFilePath); 
     Logger.debug("before call parameter from application.conf"); 
     Logger.debug("configuration.getString = "+configuration.getString("Unzipedfile.path")); 
     Logger.debug("aftercall parameter from application.conf"); 
    } 
} 

E ottengo sempre un'eccezione di puntatore nullo, in linea con configuration.getString("Unzipedfile.path")

+1

pubblicare il codice che non funziona. – marcospereira

+0

ho aggiornato come richiesto.
Lo stesso tipo di codice funziona sul mio controller application.java, ma mai sulle mie altre classi java. – Miguel

+0

Non è possibile inserire in classi arbitrarie che non sono state create da DI o che non sono state introdotte nel contesto di Guice. Se la tua classe Zipper è stata creata da Guice o iniettata da qualche parte, allora avresti il ​​contesto da iniettare. vedi http://stackoverflow.com/a/32896354/1956540 – BatteryAcid

risposta

3

ho messo qui la risposta, al fine di aiutare chiunque con lo stesso problema

Il mio errore è venuto dal modo in cui ho usato per creare un'istanza di mia Zipper classe Java da mia classe chiamata.

Thx a Igmar Palsenberg, mi ha fornito la risposta: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!topic/play-framework/uLFqTM9_Iy4

ho usato Zipper zipTest = new Zipper(); per installare la mia classe Zipper e devo usare Zipper zipTest = injector.instanceOf (Zipper.classe);

+0

Il tuo chiamante di classe è un test? – marcospereira

+0

nop, solo un livello helper e la classe zipper era una classe util, la mia comprensione è che quando uso Zipper zipTest = new Zipper(), perdo il mecanismo di Iniezione di dipendenza. per mantenerlo devo usare injector.instanceOf invece di new – Miguel

+0

Quindi, perché non stai iniettando 'Zipper' in quella classe? – marcospereira

2

Prova con iniezione costruttore, invece:

import javax.inject.Inject; 
import play.Configuration; 
import play.Logger; 

public class Zipper { 

    private Configuration configuration; 

    @Inject 
    public Zipper(Configuration config) { 
     this.configuration = config; 
    } 

    public void unZip(String zipFilePath) { 
     Logger.debug("Display : zipFilePath"+zipFilePath); 
     Logger.debug("before call parameter from application.conf"); 
     Logger.debug("configuration.getString = "+configuration.getString("Unzipedfile.path")); 
     Logger.debug("aftercall parameter from application.conf"); 
    } 
} 

Non sono sicuro che Guice sia in grado di iniettare i campi private. Ad ogni modo, l'iniezione del costruttore è il tipo di iniezione raccomandato.

+0

ho visto in questo modo, ma non sembra adattarsi alle mie necessità. – Miguel

+0

ho visto in questo modo, ma non sembra adattarsi alle mie necessità. perché se aggiorno il mio costruttore, questo significa che sulla mia classe java chiamante, dovrò iniziare questo nuovo parametro, no? con una cosa del genere Zipper zipTest = new Zipper (conf) e conf dovranno essere avviati nella mia classe java di chiamata, vorrei evitare questa situazione, e in questo caso l'iniezione sulla classe Zipper non è utile, no? potrebbe essere che ho torto, puoi mostrarmi come chiamare la classe zipper con la tua proposta? – Miguel

+0

inoltre, come ho detto di iniettare campi privati ​​funziona con controller application.java, ho questo problema solo su tutte le altre classi java – Miguel

0

Prova ad annotare la tua classe con Singleton in modo che la riproduzione possa rilevare il tuo bean per iniettare le tue risorse.

6

penso che è possibile inizializzare la configurazione come questa:

private Configuration configuration = Play.current().injector().instanceOf(Configuration .class); 

Così, il vostro Zipper sarà:

import javax.inject.Inject; 
import play.Configuration; 
import play.Logger; 

public class Zipper { 

    private Configuration configuration = Play.current().injector().instanceOf(Configuration .class); 

    public void unZip(String zipFilePath) { 
     Logger.debug("Display : zipFilePath"+zipFilePath); 
     Logger.debug("before call parameter from application.conf"); 
     Logger.debug("configuration.getString = "+configuration.getString("Unzipedfile.path")); 
     Logger.debug("aftercall parameter from application.conf"); 
    } 
} 
1

si dovrebbe cercare di rimuovere private. uso:

@Inject Configuration configuration; 

invece di:

@Inject private Configuration configuration;