Dagger 2 per sviluppatori Android inesperti. Pugnale 2.Parte 1
Questo articolo è la quarta parte di una serie di articoli destinati, secondo l'autore, a coloro che non riescono a capire come gestire l' iniezione di dipendenza e il framework Dagger 2 , o semplicemente lo faranno. Scritto originariamente il 10 dicembre 2017. Traduzione gratis.

Questo è il quarto articolo della serie Dagger 2 per sviluppatori Android principianti. ... Se non hai letto i precedenti, allora sei qui .
Abbiamo anche esaminato un semplice esempio di iniezione di dipendenza in azione. Ha preso un esempio dalla battaglia dei bastardi e ha cercato di sbarazzarsi delle forti dipendenze attraverso l'iniezione di dipendenza.
Per illustrare il problema descritto, complichiamo un po' il nostro esempio. Durante la guerra, nella battaglia dei bastardi (
La gestione manuale dell'iniezione di dipendenza è come estrarre il vetro del drago. Prima ottieni il permesso dalla regina dei draghi, poi forgi armi e solo allora vai in guerra con gli Estranei (problemi di forti legami). Dagger 2 è simile alla spada di Valyrian: è stata realizzata da artigiani e tutto ciò che devi fare è semplicemente usarla.
Questa è l'annotazione più importante. JSR-330 definisce questa annotazione come markup per le dipendenze che devono essere fornite da un framework di inserimento delle dipendenze.
Questa annotazione viene utilizzata per un'interfaccia che riunirà tutte le parti del processo di iniezione delle dipendenze. Quando si utilizza questa annotazione, determiniamo da quali moduli o altri componenti verranno prese le dipendenze. Anche qui puoi definire quali dipendenze saranno visibili apertamente (possono essere iniettate) e dove il componente può iniettare oggetti.
In altre parole, questa annotazione è come l'agente della banca di ferro, che è responsabile dell'approvazione del prestito e del trasferimento di denaro sul conto appropriato. Aggiunta di annotazioni
Il piano è iniettare le dipendenze
Il piano è creare una dipendenza o un oggetto di classe Aggiunta di annotazioni
Come abbiamo appreso in precedenza,
Ora devi ricostruire il progetto!
Dopo aver creato il progetto, vedrai che Dagger 2 ha generato una classe chiamata
Congratulazioni! Hai creato il tuo primo progetto utilizzando Dagger 2. Apprezzo davvero che tu abbia dedicato del tempo per arrivare a questo punto. Tempo di festeggiare.
Dopo aver analizzato le informazioni sui processori di annotazione e le annotazioni di base in Dagger 2 (

Questo è il quarto articolo della serie Dagger 2 per sviluppatori Android principianti. ... Se non hai letto i precedenti, allora sei qui .
Serie di articoli
- Dagger 2 per sviluppatori Android inesperti. Introduzione.
- Dagger 2 per sviluppatori Android inesperti. Iniezione di dipendenza. Parte 1 .
- Dagger 2 per sviluppatori Android inesperti. Iniezione di dipendenza. Parte 2 .
- Dagger 2 per sviluppatori Android inesperti. Pugnale 2. Parte 1 (sei qui) .
- Dagger 2 per sviluppatori Android inesperti. Pugnale 2.Parte 2 .
- Dagger 2 per sviluppatori Android inesperti. Pugnale 2. Livello avanzato.
Parte 1 . - Dagger 2 per sviluppatori Android inesperti. Pugnale 2. Livello avanzato.
Parte 2.
All'inizio della serie
Nell'ultimo articolo, ci siamo resi conto che una classe non dovrebbe creare dipendenze. Invece, dovrebbe riceverli dall'esterno.Abbiamo anche esaminato un semplice esempio di iniezione di dipendenza in azione. Ha preso un esempio dalla battaglia dei bastardi e ha cercato di sbarazzarsi delle forti dipendenze attraverso l'iniezione di dipendenza.
In che modo l'iniezione di dipendenza può complicarsi?
Se il progetto è semplice come l'esempio discusso in precedenza, creare istanze e inserire manualmente un numero limitato di dipendenze, tramite il punto di ingresso (main()
oonCreate()
metodo) nel programma è molto ragionevole. Tuttavia, in molti progetti ci sono molte classi, ognuna con diverse dipendenze che devono essere soddisfatte. Ci vuole molto codice per creare un'istanza e collegare tutto insieme. Ancora peggio, questo codice cambierà costantemente ogni volta che nuove classi vengono aggiunte all'applicazione e quando le classi esistenti vengono modificate per iniettare nuove dipendenze.Per illustrare il problema descritto, complichiamo un po' il nostro esempio. Durante la guerra, nella battaglia dei bastardi (
BattleOfBastards
) avrà probabilmente bisogno dell'aiuto degli alleati (Allies
). Anche banca di ferro (IronBank
) finanzierà le case. Il metodo principale modificato sarà simile a questo:public class BattleOfBastards {
public static void main(String[] args){
IronBank bank = new IronBank();
Allies allies = new Allies(bank);
Starks starks = new Starks(allies, bank);
Boltons boltons = new Boltons(allies, bank);
War war = new War(starks, boltons);
war.prepare();
war.report();
}
}
Molto rapidamente, il punto di ingresso dell'applicazione verrà riempito con un'enorme quantità di codice per inizializzare tutte le dipendenze. Per creare una classe, con la quale lavoreremo, dobbiamo inizializzarne molte altre. Man mano che l'applicazione cresce e vengono aggiunte nuove classi, il punto di ingresso dell'applicazione si gonfia e alla fine diventa molto difficile da mantenere.Dagger 2 si precipita in soccorso
Dagger 2 è uno dei framework open source per l'iniezione delle dipendenze (di seguito userò DI, da Dependency Injection), che genera molto codice standard per te. Perché è migliore degli altri? Attualmente è l'unico framework DI che genera codice Java completamente tracciabile che imita ciò che potresti aver scritto a mano. Ciò significa che non c'è magia nella costruzione del grafico delle dipendenze. Dagger 2 è meno dinamico di altri (non utilizza la riflessione), ma la semplicità e le prestazioni del codice generato sono allo stesso livello di quello scritto a mano. In breve, Dagger 2 genera tutto il codice standard per l'iniezione di dipendenza per te.La gestione manuale dell'iniezione di dipendenza è come estrarre il vetro del drago. Prima ottieni il permesso dalla regina dei draghi, poi forgi armi e solo allora vai in guerra con gli Estranei (problemi di forti legami). Dagger 2 è simile alla spada di Valyrian: è stata realizzata da artigiani e tutto ciò che devi fare è semplicemente usarla.
media

Comprensione dei processori di annotazione
# Annotazioni
Le annotazioni sono un tipo di metadati che possono essere associati a classi, metodi, campi e persino altre annotazioni. Le annotazioni vengono utilizzate in Java per fornire informazioni aggiuntive, in alternativa alle interfacce XML o token (interfacce vuote). È possibile accedere alle annotazioni anche in fase di esecuzione tramite il meccanismo di riflessione.# Processori di annotazione
I processori di annotazione sono generatori di codice che ti nascondono il codice standard, creandolo per te in fase di compilazione. Finché queste azioni vengono eseguite in fase di compilazione, non vi è alcun impatto negativo sulle prestazioni.# Perché dovrei conoscere i processori di annotazione?
Dagger 2 li usa. Pertanto, è possibile tracciare tutto il codice generato in fase di compilazione. Pertanto, non vi è alcun degrado delle prestazioni e gli errori sono facilmente rintracciabili.# Esempi
Vedi spesso annotazioni nelle classi@Override
... Se hai usato Butteknife ,@BindView
È anche un'annotazione che nasconde alcuni metadati dietro di essa per aiutare a generare codice.Annotazioni di Dagger 2
Diamo un'occhiata ad alcune delle annotazioni di Dagger 2 prima di usarlo. Per ora, concentriamoci su due...@Inject
e@Component
...@Inject
Questa è l'annotazione più importante. JSR-330 definisce questa annotazione come markup per le dipendenze che devono essere fornite da un framework di inserimento delle dipendenze.- Inserimento del costruttore: utilizzato con un costruttore di classi.
- Iniezione di campi: utilizzata con i campi di classe.
- Iniezione del metodo - utilizzato con i metodi
public class Starks {
/ **
* Explanation of different uses
* Inject annotations in Dagger
** /
// Feild injection
@Inject
Allies allies;
// Constructor injection
@Inject
public Starks () {
// something happens
}
// Method injection
@Inject
private void prepareForWar () {
// something happens
}
}
In altre parole, l'annotazione@Inject
dirà a Dagger quali dipendenze dovrebbero essere fornite all'oggetto dipendente. È come gli agenti della banca di ferro che negoziano con le case e determinano l'importo del credito che possono prestare alla casa.@Component
Questa annotazione viene utilizzata per un'interfaccia che riunirà tutte le parti del processo di iniezione delle dipendenze. Quando si utilizza questa annotazione, determiniamo da quali moduli o altri componenti verranno prese le dipendenze. Anche qui puoi definire quali dipendenze saranno visibili apertamente (possono essere iniettate) e dove il componente può iniettare oggetti.@Component
, in generale, qualcosa come un ponte tra@Module
(daremo un'occhiata a questa annotazione più avanti) e@Inject
...In altre parole, questa annotazione è come l'agente della banca di ferro, che è responsabile dell'approvazione del prestito e del trasferimento di denaro sul conto appropriato.
Uccidi gli Estranei con la spada di Valyria
Usiamo Dagger 2 per l'esempio della battaglia bastarda. Questo esempio richiede due dipendenze per la classeWar
-Starks
eBoltons
...Configurazione di Dagger 2
Per configurare Dagger 2 nell'uso di IntelliJ Ideabuild.gradle
file dal mio ramo di progetto. Assicurati inoltre che l'elaborazione delle annotazioni sia abilitata (File -> Impostazioni -> Compilazione, esecuzione e distribuzione -> Compilatore -> Elaborazione annotazioni -> Abilita elaborazione annotazioni (il flag deve essere impostato)). Non dimenticare di notare anche questo: File -> Impostazioni -> Crea, esecuzione e distribuzione -> Gradle -> Runner -> Delega build / esegui azioni IDE su culla. Aggiunta di annotazioni@Inject
Il piano è iniettare le dipendenzeStarks
eBoltons
andare in classeWar
con l'aiuto di Dagger 2. Quello che dobbiamo dirgli esplicitamente. Di seguito è riportato un esempio di come eseguire questa operazione utilizzando l'iniezione del costruttore.public class Boltons implements House {
@Inject // Dagger 2
public Boltons () {
}
@Override
public void prepareForWar () {
// something happens
System.out.println (this.getClass (). GetSimpleName () + "prepared for war");
}
@Override
public void reportForWar () {
// something happens
System.out.println (this.getClass (). GetSimpleName () + "reporting ..");
}
}
public class Starks implements House {
@Inject // Dagger 2
public Starks () {
}
@Override
public void prepareForWar () {
// something happens
System.out.println (this.getClass (). GetSimpleName () + "prepared for war");
}
@Override
public void reportForWar () {
// something happens
System.out.println (this.getClass (). GetSimpleName () + "reporting ..");
}
}
Queste due dipendenze sono usate nel costruttore della classeWar
dove dovremmo contrassegnarlo.Il piano è creare una dipendenza o un oggetto di classe
War
disponibile per tutte le altre classi. Ma per il lavoro in classeWar
è necessario fornirgli due classi da cui dipende -Starks
eBoltons
...public class War {
private Starks
private Boltons boltons;
@Inject
public War(Starks starks, Boltons bolton){
this.starks = starks;
this.boltons = bolton;
}
public void prepare(){
starks.prepareForWar();
boltons.prepareForWar();
}
public void report(){
starks.reportForWar();
boltons.reportForWar();
}
}
Aggiunta di annotazioni@Component
Come abbiamo appreso in precedenza,@Component
È il ponte tra il codice generato e le dipendenze. Anche@Component
dice a Dagger 2 come iniettare la dipendenza. Facciamo un'interfacciaBattleComponent
all'interno della classeBattleOfBastards
(può essere fatto separatamente).@Component
interface BattleComponent {
War getWar();
}
Questa interfaccia sarà implementata dalla classe che genererà Dagger 2 e dalla funzionegetWar()
restituirà un'istanzaWar
che possiamo usare in un luogo adatto.Ora devi ricostruire il progetto!
Dopo aver creato il progetto, vedrai che Dagger 2 ha generato una classe chiamata
DaggerBattleComponent
- ci aiuterà a implementare la classeWar
... Usiamo questa classe per ottenere un'istanzaWar
...@Component
interface BattleComponent {
War getWar ();
}
public class BattleOfBastards {
public static void main (String [] args) {
// Manual dependency injection
// Starks starks = new Starks ();
// Boltons boltons = new Boltons ();
// War war = new War (starks, boltons);
// war.prepare ();
// war.report ();
// Using Dagger 2
BattleComponent component = DaggerBattleComponent.create ();
War war = component.getWar ();
war.prepare ();
war.report ();
}
}
Usando la classeDaggerBattleComponent
possiamo usare il metodogetWar()
che restituisce un'istanzaWar
che inietta le dipendenzeStarks
eBoltons
...Congratulazioni! Hai creato il tuo primo progetto utilizzando Dagger 2. Apprezzo davvero che tu abbia dedicato del tempo per arrivare a questo punto. Tempo di festeggiare.
Sommario
Abbiamo discusso di come l'uso manuale di DI aggiunge complessità e codice standard. Quindi abbiamo discusso di come Dagger 2 ci aiuta a sbarazzarci di questo dolore e genera il codice standard stesso.Dopo aver analizzato le informazioni sui processori di annotazione e le annotazioni di base in Dagger 2 (
@Inject
e@Component
). Quindi abbiamo applicato le annotazioni nel nostro esempio e abbiamo inserito le dipendenze utilizzando Dagger 2.