Java Dependency Injection-DI Design Pattern Example Tutorial

Java Dependency Injection design pattern stelt ons in staat om de hard-gecodeerde afhankelijkheden te verwijderen en onze applicatie losjes gekoppeld, uitbreidbaar en onderhoudbaar te maken. We kunnen afhankelijkheidsinjectie in java implementeren om de afhankelijkheidsresolutie van compilatietijd naar runtime te verplaatsen.,

Java Dependency Injection

Java Dependency injection lijkt moeilijk te begrijpen met theorie, dus ik zou een eenvoudig voorbeeld nemen en dan zullen we zien hoe afhankelijkheid injectie patroon te gebruiken om losse koppeling en uitbreidbaarheid in de toepassing te bereiken.

laten we zeggen dat we een toepassing hebben waarin we EmailServicegebruiken om e-mails te verzenden. Normaal gesproken zouden we dit implementeren zoals hieronder.

EmailService klasse bevat de logica om een e-mailbericht naar het e-mailadres van de ontvanger te sturen., Onze toepassingscode is zoals hieronder.

onze client code die MyApplication klasse zal gebruiken om e-mailberichten te verzenden zal zijn zoals hieronder.

op het eerste gezicht lijkt er niets mis te zijn met de bovenstaande implementatie. Maar bovenstaande code logica heeft bepaalde beperkingen.

  • MyApplicationklasse is verantwoordelijk voor het initialiseren van de e-mailservice en deze vervolgens te gebruiken. Dit leidt tot hard-gecodeerde afhankelijkheid. Als we in de toekomst naar een andere geavanceerde e-mailservice willen overschakelen, vereist dit codewijzigingen in de klasse MyApplication., Dit maakt onze applicatie moeilijk uit te breiden en als e-mail service wordt gebruikt in meerdere klassen dan zou dat nog moeilijker zijn.
  • als we onze applicatie willen uitbreiden om een extra berichtenfunctie te bieden, zoals SMS of Facebook-bericht, dan moeten we daarvoor een andere applicatie schrijven. Dit zal codewijzigingen in applicatieklassen en ook in clientklassen omvatten.
  • het testen van de applicatie zal erg moeilijk zijn omdat onze applicatie direct de e-mail service instance aanmaakt. Er is geen manier waarop we deze objecten kunnen bespotten in onze test klassen.,

men kan stellen dat we de creatie van een e-mailservice-instantie uit MyApplication klasse kunnen verwijderen door een constructor te hebben die e-mailservice als argument nodig heeft.

maar in dit geval vragen we clienttoepassingen of testklassen om de e-mailservice te initialiseren, wat geen goede ontwerpbeslissing is.

laten we nu eens kijken hoe we java dependency injection pattern kunnen toepassen om alle problemen met de bovenstaande implementatie op te lossen., Afhankelijkheid injectie in java vereist ten minste het volgende:

  1. Service componenten moeten worden ontworpen met basis klasse of interface. Het is beter om de voorkeur te geven aan interfaces of abstracte klassen die contract voor de diensten zouden definiëren.
  2. Consumer classes moeten worden geschreven in termen van service interface.
  3. Injector classes die de services en vervolgens de consumer classes zullen initialiseren.

Java Dependency Injection-Service Components

voor ons geval kunnen we MessageService hebben die het contract voor service implementaties zal declareren.,

package com.journaldev.java.dependencyinjection.service;public interface MessageService {void sendMessage(String msg, String rec);}

laten we nu zeggen dat we e-mail en SMS diensten hebben die de bovenstaande interfaces implementeren.

onze dependency injection java services zijn klaar en nu kunnen we onze consumer class schrijven.

Java Dependency Injection-Service Consumer

We zijn niet verplicht om basisinterfaces voor consumer classes te hebben, maar Ik zal een Consumer interface hebben die contract voor consumer classes verklaart.

package com.journaldev.java.dependencyinjection.consumer;public interface Consumer {void processMessages(String msg, String rec);}

mijn consumer class implementatie is zoals hieronder.

merk op dat onze toepassingsklasse alleen de service gebruikt., Het is niet de dienst die leidt tot een betere “scheiding van zorgen” initialiseren. Ook het gebruik van de service-interface stelt ons in staat om de applicatie eenvoudig te testen door de MessageService te bespotten en de services tijdens runtime te binden in plaats van de compilatietijd.

nu zijn we klaar om java dependency injector classes te schrijven die de service en ook consumer classes zullen initialiseren.

Java Dependency Injection-Injectors Classes

laten we een interface hebben MessageServiceInjector met methodedeclaratie die de Consumer klasse retourneert.,

package com.journaldev.java.dependencyinjection.injector;import com.journaldev.java.dependencyinjection.consumer.Consumer;public interface MessageServiceInjector {public Consumer getConsumer();}

nu moeten we voor elke service injector klassen maken zoals hieronder.

package com.journaldev.java.dependencyinjection.injector;import com.journaldev.java.dependencyinjection.consumer.Consumer;import com.journaldev.java.dependencyinjection.consumer.MyDIApplication;import com.journaldev.java.dependencyinjection.service.EmailServiceImpl;public class EmailServiceInjector implements MessageServiceInjector {@Overridepublic Consumer getConsumer() {return new MyDIApplication(new EmailServiceImpl());}}
package com.journaldev.java.dependencyinjection.injector;import com.journaldev.java.dependencyinjection.consumer.Consumer;import com.journaldev.java.dependencyinjection.consumer.MyDIApplication;import com.journaldev.java.dependencyinjection.service.SMSServiceImpl;public class SMSServiceInjector implements MessageServiceInjector {@Overridepublic Consumer getConsumer() {return new MyDIApplication(new SMSServiceImpl());}}

laten we nu eens kijken hoe onze client applicaties de toepassing met een eenvoudig programma zullen gebruiken.

zoals u kunt zien zijn onze toepassingsklassen alleen verantwoordelijk voor het gebruik van de service. Service klassen worden gecreëerd in injectoren. Ook als we onze applicatie verder moeten uitbreiden om facebook messaging toe te staan, zullen we alleen serviceklassen en injectorklassen moeten schrijven.,

dus implementatie van dependency injection loste het probleem op met hard-gecodeerde afhankelijkheid en hielp ons bij het flexibel maken van onze toepassing en gemakkelijk uit te breiden. Laten we nu eens kijken hoe gemakkelijk we onze toepassingsklasse kunnen testen door de injector-en serviceklassen te bespotten.

Java Dependency Injection-JUnit Test Case with Mock Injector and Service

zoals u kunt zien gebruik ik anonieme klassen om de injector en service klassen te bespotten en ik kan gemakkelijk mijn toepassingsmethoden testen., Ik gebruik JUnit 4 voor de bovenstaande test klasse, dus zorg ervoor dat het in uw project build pad als je draait boven test klasse.

we hebben constructors gebruikt om de afhankelijkheden in de toepassingsklassen te injecteren, een andere manier is om een setter methode te gebruiken om afhankelijkheden in toepassingsklassen te injecteren. Voor setter method dependency injection zal onze toepassingsklasse worden geïmplementeerd zoals hieronder.

package com.journaldev.java.dependencyinjection.injector;import com.journaldev.java.dependencyinjection.consumer.Consumer;import com.journaldev.java.dependencyinjection.consumer.MyDIApplication;import com.journaldev.java.dependencyinjection.service.EmailServiceImpl;public class EmailServiceInjector implements MessageServiceInjector {@Overridepublic Consumer getConsumer() {MyDIApplication app = new MyDIApplication();app.setService(new EmailServiceImpl());return app;}}

een van de beste voorbeelden van setter dependency injection is Struts2 Servlet API Aware interfaces.,

of Constructor-gebaseerde dependency injection of setter-gebaseerde injectie moet worden gebruikt, is een ontwerpbeslissing en hangt af van uw vereisten. Bijvoorbeeld, als mijn applicatie helemaal niet kan werken zonder de service Klasse dan zou ik liever constructor gebaseerde DI of anders zou ik gaan voor setter methode gebaseerde DI om het alleen te gebruiken wanneer het echt nodig is.

Dependency Injection in Java is een manier om inversie van controle (IoC) te bereiken in onze applicatie door het verplaatsen van objecten binding van compileertijd naar runtime., We kunnen IOC bereiken door middel van fabriek patroon, Template methode Ontwerp Patroon, strategie patroon en Service Locator patroon ook.

Spring Dependency Injection, Google Guice en Java EE CDI frameworks vergemakkelijken het proces van dependency injection door het gebruik van Java reflectie API en java annotaties. Alles wat we nodig hebben is om het veld te annoteren, constructor of setter methode en configureer ze in configuratie xml-bestanden of klassen.,tion

een van de voordelen van het gebruik van Dependency Injection in Java zijn:

  • Scheiding van zaken
  • Boilerplate Code vermindering in de toepassing klassen, omdat al het werk te initialiseren afhankelijkheden wordt afgehandeld door de injector component
  • Instelbare onderdelen maakt toepassing eenvoudig uitbreidbaar te zijn
  • Unit testen is eenvoudig met mock objects

Nadelen van Java-Dependency Injection

Java-Dependency injection heeft ook nadelen:

  • Als er te veel gebruikt, het kan leiden tot het onderhoud van problemen omdat het effect van de wijzigingen bekend zijn bij de uitvoering.,
  • Dependency injection in java verbergt de service class afhankelijkheden die kunnen leiden tot runtime fouten die zouden zijn gevangen tijdens het compileren.

dat is alles voor dependency injection patroon in java. Het is goed om te weten en te gebruiken wanneer we de controle over de diensten.

Leave a Comment