„A függőség befecskendezése” változatai közötti eltérés

A Wikipédiából, a szabad enciklopédiából
[ellenőrzött változat][ellenőrzött változat]
Tartalom törölve Tartalom hozzáadva
294. sor: 294. sor:
</beans>
</beans>
</source>
</source>

A fenti példában a Client és a Service nem ment át olyan a változásokon, amilyeneket a Spring képes nyújtani, egyszerű POJO-k maradtak.<ref>{{Cite web|title = Spring Tips: A POJO with annotations is not Plain|url = http://springtips.blogspot.com/2007/07/pojo-with-annotations-is-not-plain.html|accessdate = 2015-07-18}}</ref><ref>{{Cite web|title = Annotations in POJO – a boon or a curse? {{!}} Techtracer|url = http://techtracer.com/2007/04/07/annotations-in-pojo-a-boon-or-a-curse/|accessdate = 2015-07-18}}</ref><ref>
{{cite web
|url=https://books.google.com/books?id=FCVnsq1ZUI0C&pg=PA64&lpg=PA64&dq=spring+pojo+annotation+free&source=bl&ots=YzORtPWR8g&sig=6evcrQuZzscyLIT6uggpyCKn5Sc&hl=en&sa=X&ei=4GCaVcb7EoWMNpC0mdgM&ved=0CGIQ6AEwCQ#v=onepage&q=spring%20pojo%20annotation%20free&f=false|title=Pro Spring Dynamic Modules for OSGi Service Platforms|publisher=APress |accessdate=2015-07-06}}
</ref> A példa azt mutatja, hogy a Spring képes összekapcsolni egymásról semmit sem tudó objektumokat. Ez nem mondható el, ha elhelyeznek néhány Spring annotációt a kódban. Az annotációkkal a rendszer függetlenebbé válik a Springtől,<ref name="sites.google.com"/> ami fontos, ha egy szép nap a projektmenedzser kitalálja, hogy át kell térni egy másik keretrendszerre, mert az esetleg többet tud.


==Jegyzetek==
==Jegyzetek==

A lap 2017. október 6., 20:50-kori változata

A számítógép-programozásban a dependency injection egy technika, aminek lényege, hogy egy objektum más objektumok függőségeit követeli. A függőség objektum szolgáltatást nyújt, az injekció pedig a függőség átadása a függő objektumnak, a kliensnek. A szolgáltatás a kliens állapotának része.[1] A minta alapkövetelménye a szolgáltatás kliensnek való átadása ahelyett, hogy a szolgáltató objektumot a kliens hozná létre.

A szolgáltató osztály szempontjából ez azt jelenti, hogy a kliens nem hívhat rajta konstruktort, vagy statikus metódust. Paramétereit más osztályoktól kapja, azok állítják be. A függőséget előállítja valaki más, például a kontextus vagy a konténer problémája lesz.

A minta célja, hogy annyira leválassza a szolgáltató objektumot a kliensről, hogy ha kicserélik, akkor ne kelljen módosítani a klienst.

A dependency injection a vezérlés megfordításának egyik formája. Ahelyett, hogy az alacsony szintű kód hívná a magas szintűt, a magas szintű fogadja az alacsony szintűt, amit hívhat. Ez megfordítja a procedurális programozás szokásos vezérlési mintáját.

Ahogy a vezérlés megfordításának többi formája, a dependency injection alkalmazza a felelősség megfordításának elvét. A kliens külső kódnak delegálja függőségeinek létrehozását az injektornak, amit azonban nem hívhat.[2] Fordítva, az injektor hívja a klienst, és adja át neki az objektumot. A kliensnek nem kell tudnia, hogyan kell létrehozni a szolgáltatót, és nem kell tudnia az injektor kódról sem. Csak a szolgáltató interfészét kell ismernie, mert ez definiálja, hogyan hívhatja meg a szolgáltatásokat. Ez elkülöníti egymástól a létrehozás és a használat felelősségét.

A kliens három különböző módon fogadhatja a szolgáltatásokat: szetter, interfész és konstruktor alapú injekcióban. A szetter és a konstruktor injekció abban különbözik, hogy mikor lehet őket használni. Ezektől az interfész alapú injekció abban különbözik, hogy a szolgáltató objektum ellenőrizheti injekcióját. Mindezek megkövetelik, hogy egy külön kód, az injektor hozza létre a kapcsolatot a másik két elem között.[3]

Céljai

A dependency injection a következő problémákat oldja meg:[4]

  • Hogyan lehet az alkalmazás független attól, hogyan hozzák létre az objektumait?
  • Hogyan lehet egy objektum független attól, hogy az általa megkövetelt objektumok hogyan jönnek létre?
  • Hogyan lehet elérni azt, hogy minden objektum tulajdonságait külön konfigurációs fájlban lehessen megadni?
  • Hogyan támogathat az alkalmazás több különböző konfigurációt?

Az objektumok létrehozása a kliens osztályban merevvé teszi a kódot, mivel ezután az objektum csak a megadott osztályú másik objektumot hozhatja létre és használhatja. Lehetetlenné válik, hogy a tartalmazott objektumot kicseréljék a kliens módosítása nélkül. Ez megnehezíti az újrahasználását és a tesztelést is, mert mókolás előtt és után vigyázni kell, hogy most melyik objektumot használjuk, és plusz hibalehetőség adódik.

A dependency ijection minta megoldást nyújt erre a problémára:

  • Injektor osztály létrehozása, ami létrehozza és injektálja az objektumokat
  • Az osztály a közvetlen létrehozás helyett az injektortól kapja az objektumokat.

Az osztály így függetlenné válik attól, hogyan hozzák létre a szükséges objektumait, és hogy melyik konkrét osztály tagját használja. A dependency injection miatt az objektumnak nem kell a többi létrehozási mintának (absztrakt gyár, gyártó minta, gyártó metódus, ...) delegálnia az objektum létrehozását. Ez leegyszerűsíti az osztályokat, a megvalósítást, változtatást, tesztelést és újrafelhasználást.[5] design pattern.

Áttekintése

Dependency injection ötéveseknek

Ha kimész a konyhába, és előveszel magadnak valamit enni, akkor problémát okozhatsz. Nyitva hagyhatod az ajtót, elővehetsz valamit, amit a szüleid nem akarnak, hogy megegyél. Olyat kereshetsz, ami nincs bent, vagy elővehetsz valamit, ami meg van romolva.

Ehelyett, ha azt mondod: "Szeretnék valamit enni és inni", akkor biztos lehetsz abban, hogy lesz mit enned és innod, és nem okozol problémát.

John Munsch, 28 October 2009.[6][7][8]

A dependency injection a függőség megfordítása és az egyértelmű felelősség elvét követve[6][9] meglazítja az objektumok közötti csatolást azáltal,[10] hogy elkülöníti a létrehozást és a használatot. Vele szemben áll a szolgáltatáslokátor, ami megengedi a klienseknek, hogy tudomásuk legyen a rendszer egy részéről, hogy megtalálják függőségeiket.

Alapegysége az injekció, ami a paraméterátadáshoz hasonlóan működik.[11] A paraméterátadásra hivatkozva nyilvánvalóvá válik, hogy ez azért van, hogy a klienst elszigetelje a részletektől. Az injekció azt is jelenti, hogy az átadás független a klienstől, és független attól, hogy hogyan valósul meg, érték vagy referencia szerint.

A dependency injection elemei:

  • Szolgáltató objektum
  • Kliens
  • Interfész, amin keresztül a kliens a szolgáltató objektumot látja
  • Injektor, ami létrehozza, beállítja és injektálja a szolgáltató objektumot

A kliens egy objektum, ami igénybe vesz egy másik objektumot. A szolgáltató objektum az, ami szolgáltatást nyújt egy kliens részére. Egy objektum lehet egyszer kliens, másszor szolgáltató objektum.

Az interfész a kliens által elvárt típus. A kliens csak azt láthatja, amit az interfész előír, a szolgáltató objektum többi nyilvános vagy félnyilvános műveletét sem hívhatja. Az interfész lehet interfész, absztrakt osztály vagy konkrét osztály is. Ez utóbbi azonban megsérti a függőség megfordításának elvét,[12] és feláldozza a dinamikus kapcsolatot, ami megkönnyítené a tesztelést. A kliens nem tudhatja, hogy ez pontosan mi, nem tekintheti konkrétnak, nem származtathat belőle vagy hozhat létre saját maga elemet belőle.

A kliens nem ismerheti a szolgáltató objektum konkrét megvalósítását, csak az interfészét és az API-t. A szolgáltató objektum változásai egészen addig nem érintik a klienst, amíg az interfész nem változik. Ha az interfész valódi interfészből osztály lesz vagy megfordítva, akkor a klienst újra kell fordítani.[13] Ez fontos, ha a klienst és a szolgáltató objektumot külön adják ki, például ha egy plugint kell használni.

Az injektor odaadja a szolgáltató objektumot a kliensnek. Gyakran ő is hozza létre és állítja be. Az injektor összekapcsolhat egy bonyolult objektumgráfot azzal, hogy egy objektum hol kliens, hol szolgáltató objektum. Alkothatja több különböző osztályú objektum, de a kliens nem lehet köztük. Az injektorra más neveken is hivatkoznak: assembler, szolgáltató, konténer, gyár, építő, spring, konstrukciós kód vagy main.

A minta alkalmazható architekturális szinten úgy, hogy minden összetett objektum így veszi át részobjektumait. A dependency injection keretrendszer akár be is tilthatja a new kulcsszó használatát, vagy csak érték objektumok létrehozását engedélyezheti.[14][15][16][17]

Taxonómia

A vezérlés megfordítása általánosabb, mint a dependency injection. Az előbbi a Hollywood-elven alapul: Ne hívj, mi hívunk téged. Egy másik példa a sablonfüggvény programtervezési minta, ahol a polimorfizmust öröklődéssel érjük el.[18]

A stratégia programtervezési mintához hasonlóan a dependency injection kompozícióval valósítja meg a vezérlés megfordítását. De míg az az objektum élete alatt is fenntartja a példány kicserélődésének lehetőségét, addig ez többnyire egyetlen példányt használ a kliens életideje alatt.[19] Így a polimorfizmus a kompozícióval és delegációval valósul meg.

Keretrendszerek

Alkalmazás keretrendszerek, mint CDI és megvalósításai Weld, Spring, Guice, Play framework, Salta, Glassfish HK2, Dagger, és Managed Extensibility Framework (MEF) támogatják, de nem teszik kötelezővé a dependency injectiont.[20][21]

Előnyei

  • A dependency injection meghagyja a kliensnek a rugalmasságát a konfiguráció tekintetében. Csak a kliens viselkedése rögzített. A kliens bármivel működik, ami támogatja a kliens által elvárt interfészt.
  • A minta használható arra, hogy a rendszer konfigurációjának részletei konfigurációs fájlokban legyenek megadva, Különböző környezetekhez, helyzetekhez különböző konfigurációs fájlokban különböző konfigurációkat lehet megadni.
  • Mivel nem követeli meg a kliens kód megváltoztatását, alkalmas arra, hogy legacy kódot támogasson. Eredménye az, hogy a kliensek függetlenebbek, ezért egyszerűbb egységteszteket végezni. Dependency injection alkalmazásakor gyakran ez az első előny, amit észrevesznek.
  • A minta lehetővé teszi, sőt megköveteli, hogy a kliensből eltávolítsanak minden tudást, ami az általa használt objektumok konkrét megvalósításának részleteit tartalmazza. Támogatja a karbantarthatóságot és az újrafelhasználhatóságot.[22]
  • Az alkalmazásobjektumokban levő szószátyár kód (boilerplate) csökkenése, mivel az inicializálást és beállítást külön komponens végzi.[22]
  • Segíti a független és a párhuzamos fejlesztést. Az egymást használó osztályok szétoszthatók különböző fejlesztők között, mivel csak egy közös interfészt kell ismerniük. Felhasználhatók olyan pluginok, amelyek fejlesztőivel nem lehetett megbeszélni a részleteket.
  • A minta gyengíti a kapcsolatot a kliens és a szolgáltató objektum között.[23][24]

Hátrányai

  • A kliensek konfigurációs fájlt követelnek, amikor az alapértelmezett értékeknek maguktól kell értődniük. Ez bosszantó lehet, és hibalehetőséget is jelent.
  • A létrehozás és a viselkedés elkülönítése miatt több fájlban kell nyomon kvetelni a rendszer viselkedését. Ez bonyolultabbá teszi a hibák helyének megtalálását.
  • A minta rendszerint a fejlesztés irányát és sorrendjét is megszabja. Ha egy objektum az egységtesztek során megfelelőnek látszik, akkor még azt is igazolni kell, hogy az injekció valóban működik.
  • A bonyolultság a fájlokból átkerül a fájlok rendszerébe, ami nem mindig kívánatos, vagy kezelhető könnyen.[25]
  • A dependency injection arra csábíthatja a fejlesztőket, hogy függjenek egy keretrendszertől.[25][26][27]

Szerkezete

Példa UML osztály- és folyamatdiagram for the Dependency Injection design patterna dependency injection mintáról. [28]

A fenti UML osztálydiagramon a Client osztály nem példányosítja közvetlenül a ServiceA1 és ServiceB1 osztályokat. Neki ServiceA és ServiceB típusú objektumok kellenek, amiket az Injector hoz létre, és injektál a Clientbe. Ezzel a Client függetlenné válik attól, hogyan hozzák létre az általa használt objektumokat, így a konkrét osztályok helyett csak azok általánosításáról tud.

Az UML folyamatdiagram a futásidejű történéseket mutatja: Az Injector létrehozza a ServiceA1 és ServiceB1 osztályú objektumokat. Ezután az Injector létrehozza a Clientet is, és odaadja neki a ServiceA és ServiceB osztályú objektumokat.

Példa

Közvetlen példányosítás

A következő Java példában a Client osztály egyik mezőjében tartalmaz egy Service osztályú objektumot, amit a Client konstruktora inicializál. A Client dönti el, hogy melyik megvalósítást használja, és ellenőrzi a konstrukciós folyamatot. Ekkor a Client erősen függ a ServiceExample osztálytól.

// An example without dependency injection
public class Client {
    // Internal reference to the service used by this client
    private ServiceExample service;

    // Constructor
    Client() {
        // Specify a specific implementation in the constructor instead of using dependency injection
        service = new ServiceExample();
    }

    // Method within this client that uses the services
    public String greet() {
        return "Hello " + service.getName();
    }
}

Ezzel szemben a dependency injection csak az inicializációt engedi meg, az explicit példányosítást nem.

A dependency injection fajtái

Az osztály legalább háromféleképpen szerezhet referenciát egy külső modulra:[29]

  • konstruktor injekció: a szolgáltató objektumokról a konstruktor gondoskodik.
  • szetter injekció: a szolgáltató objektumot a szetter igényli
  • interfész injekció: a szolgáltató objektumnak van injektáló metódusa, ami injektálja bármely kliensbe, amit megkap paraméterként. A klienseknek meg kell valósítaniuk egy interfészt, ami előír egy szetter metódust, ami fogadja az injekciót.

Keretrendszerek lehetővé tehetnek más formájú dependency injectionöket is.[30]

Teszt keretrendszerekben még azt sem követelik meg, hogy a kliens aktívan fogadja a dependency injectiont, ezzel a legacy kód is tesztelhető. Speciálisan, a tesztek használhatnak reflexiót is, amivel hozzáférhetnek a privát adattagokhoz is, így értékadással fogadhatnak injekciót.[31]

A vezérlés megfordítása nem távolítja el teljesen a függőséget, csak helyettesíti egy másikkal. Ökölszabály, hogy ha egy programozó a kliens kódját látva azonosítani tudja a keretrendszert, akkor a kliens erősen függ a keretrendszertől.

Konstruktor injekció

A kliens konstruktora paraméterként veszi át a szolgáltató objektumot:

// Constructor
Client(Service service) {
    // Save the reference to the passed-in service inside this client
    this.service = service;
}

Szetter injekció

A kliens szetterben veszi át a szolgáltató objektumot, mint paramétert:

// Setter method
public void setService(Service service) {
    // Save the reference to the passed-in service inside this client
    this.service = service;
}

Interfész injekció

A kliens csak az interfészt adja meg a szolgáltató objektumokat beállító függvények számára. Meghatározhatja, hogyan beszélhet az injektor a klienshez injektáláskor.

// Service setter interface.
public interface ServiceSetter {
    public void setService(Service service);
}

// Client class
public class Client implements ServiceSetter {
    // Internal reference to the service used by this client.
    private Service service;

    // Set the service that this client is to use.
    @Override
    public void setService(Service service) {
        this.service = service;
    }
}

Konstruktor injekció összehasonlítás

A konstruktor injekció előnyben részesítendő, ha az összes szolgáltató objektum megkonstruálható a kliensnél korábban. Ezzel biztosítható, hogy a kliens állapota mindig érvényes legyen. Ezzel szemben hiányzik az a rugalmassága, hogy később meg lehessen változatatni a szolgáltató objektumait. Ez lehet az első lépés afelé, hogy a kliens megváltoztathatatlan legyen, ezzel szálbiztossá váljon.

// Constructor
Client(Service service, Service otherService) {
    if (service == null) {
        throw new InvalidParameterException("service must not be null");
    }
    if (otherService == null) {
        throw new InvalidParameterException("otherService must not be null");
    }

    // Save the service references inside this client
    this.service = service;
    this.otherService = otherService;
}

Szetter injekció összehasonlítás

A kliensnek minden szolgáltató objektumához szetter kell, így azok bármikor megváltoztathatók. Ez rugalmasságot biztosít, viszont nehezebb biztosítani, hogy mindig mindegyik szolgáltató objektum rendelkezésre álljon.

// Set the service to be used by this client
public void setService(Service service) {
    if (service == null) {
        throw new InvalidParameterException("service must not be null");
    }
    this.service = service;
}

// Set the other service to be used by this client
public void setOtherService(Service otherService) {
    if (otherService == null) {
        throw new InvalidParameterException("otherService must not be null");
    }
    this.otherService = otherService;
}

Mivel az injekciók függetlenek egymástól, sosem lehet tudni, hogy az injektor végzett-e a beállítással. Egy szolgáltató objektum null maradhat, ha az injektor ne tudta meghívni a szetterét. Emiatt ellenőrizni kell a klienst, mielőtt további használatba adjuk.

// Set the service to be used by this client
public void setService(Service service) {
    this.service = service;
}

// Set the other service to be used by this client
public void setOtherService(Service otherService) {
    this.otherService = otherService;
}

// Check the service references of this client
private void validateState() {
    if (service == null) {
        throw new IllegalStateException("service must not be null");
    }
    if (otherService == null) {
        throw new IllegalStateException("otherService must not be null");
    }
}

// Method that uses the service references
public void doSomething() {
    validateState();
    service.doYourThing();
    otherService.doYourThing();
}

Konstruktor injekció összehasonlítás

Az interfész injekció előnye, hogy a szolgáltató objektumoknak nem kell tudniuk a kliensekről, habár mindig kapnak referenciát az új kliensre, amivel visszahívják a klienst, és átadják magukat referenciaként. Így a szolgáltató objektumok injektorokká válnak. Az injektáló metódust a szolgáltató objektum interfésze írja elő, és akár egyszerű szetter metódus is lehet.

Még mindig szükség van egy mediátorra, ami bemutatja egymásnak a szolgáltató objektumokat és a klienseket. Ez átvesz egy hivatkozást a kliensre, átadja a szetter interfésznek, ami beállítja a szolgáltató objektumot, ezután visszaadja a szolgáltató objektumnak, ami visszaad egy rá mutató referenciát.

Hogy legyen értéke az interfész injekciónak, a szolgáltató objektumnak további műveleteket is kell végeznie. Ez lehet az, hogy gyárként működik, hogy feloldja a további függőségeket, és részleteket vonatkoztat el a fő közvetítőtől. Végezhet referenciaszámlálást, ebből megtudhatja, hány kliens használja. Ha adatszerkezetben tárolja őket, akkor később injektálhatja őket egy másik példányába.

Összegyűjtési példa

A dependency injection megvalósításának egyik módja az, ha kézzel gyűjtjük össze a szereplőket a mainben:

public class Injector {
    public static void main(String[] args) {
        // Build the dependencies first
        Service service = new ServiceExample();

        // Inject the service, constructor style
        Client client = new Client(service);

        // Use the objects
        System.out.println(client.greet());
    }	
}

A fenti példa kézzel hozza létre az objektumgráfot, és meghívja egy ponton, ezzel elindítva a működést. Fontos megjegyezni, hogy ez az injektor nem tiszta, mert az elindítással használ egy általa létrehozott objektumot. Hasonlít a csak konstruáló ServiceExample-hoz, de keveri a konstrukciót és a kliens felhasználását. Habár ez elkerülhetetlen, nem szabad általánosnak lennie. Ahogy az objektumorientált programozásban van nem objektumorientált main metódus, úgy a dependency injektion objektumgráéfjának is kell belépési pont, ha lehet, akkor csak egy.

A main függvény a létrehozáshoz használhat különféle létrehozási tervmintákat, mint absztrakt gyár, gyártó metódus, építő. Ezek a minták lehetnek absztraktak, ami már elmozdulás a keretrendszer felé, mivel a konstrukciós kód univerzális.[32]

A keretrendszerek, mint a Spring is létrehozhatja ugyanezeket az objektumokat, és összekapcsolhatja őket, mielőtt még referenciát adna a kliensre. Jegyezzük meg, hogy az alábbi kód meg sem említi a ServiceExample-t:

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Injector {
	public static void main(String[] args) {
		// -- Assembling objects -- //
		BeanFactory beanfactory = new ClassPathXmlApplicationContext("Beans.xml");
		Client client = (Client) beanfactory.getBean("client");

		// -- Using objects -- //
		System.out.println(client.greet());
	}
}

A keretrendszerek azt is lehetővé teszik, hogy a részleteket konfigurációs fájlokba emeljük ki. A fenti kód létrehozza az objektumokat, és a Beans.xml alapján összekapcsolja őket. Létrejön a ServiceExample is, habár csak a konfigurációs fájl említi. A fájlban nagy és összetett objektumgráfot lehet definiálni, és csak a belépési metódust kell explicit hívni, ami ebben az esetben a greet().

 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="service" class="ServiceExample">
    </bean>

    <bean id="client" class="Client">
        <constructor-arg value="service" />        
    </bean>
</beans>

A fenti példában a Client és a Service nem ment át olyan a változásokon, amilyeneket a Spring képes nyújtani, egyszerű POJO-k maradtak.[33][34][35] A példa azt mutatja, hogy a Spring képes összekapcsolni egymásról semmit sem tudó objektumokat. Ez nem mondható el, ha elhelyeznek néhány Spring annotációt a kódban. Az annotációkkal a rendszer függetlenebbé válik a Springtől,[26] ami fontos, ha egy szép nap a projektmenedzser kitalálja, hogy át kell térni egy másik keretrendszerre, mert az esetleg többet tud.

Jegyzetek

  1. I.T., Titanium: James Shore: Dependency Injection Demystified. www.jamesshore.com . (Hozzáférés: 2015. július 18.)
  2. HollywoodPrinciple. http://c2.com . (Hozzáférés: 2015. július 19.)
  3. Inversion of Control Containers and the Dependency Injection pattern. (Hozzáférés: 2015. július 18.)
  4. The Dependency Injection design pattern - Problem, Solution, and Applicability. w3sDesign.com . (Hozzáférés: 2017. augusztus 12.)
  5. Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley, 87ff. o. (1994). ISBN 0-201-63361-2 
  6. a b Dependency Injection in .NET. Manning Publications, 4. o. (2011. október 1.). ISBN 9781935182504 
  7. Dependency Injection in NET. http://philkildea.co.uk . (Hozzáférés: 2015. július 18.)
  8. How to explain dependency injection to a 5-year-old?. stackoverflow.com . (Hozzáférés: 2015. július 18.)
  9. Niko Schwarz, Mircea Lungu, Oscar Nierstrasz, “Seuss: Decoupling responsibilities from static methods for fine-grained configurability”, Journal of Object Technology, Volume 11, no. 1 (April 2012), pp. 3:1-23
  10. Seemann, Mark: Dependency Injection is Loose Coupling. blog.ploeh.dk . (Hozzáférés: 2015. július 28.)
  11. Passing Information to a Method or a Constructor (The Java™ Tutorials > Learning the Java Language > Classes and Objects). docs.oracle.com . (Hozzáférés: 2015. július 18.)
  12. A curry of Dependency Inversion Principle (DIP), Inversion of Control (IoC), Dependency Injection (DI) and IoC Container - CodeProject. www.codeproject.com . (Hozzáférés: 2015. augusztus 8.)
  13. How to force "program to an interface" without using a java Interface in java 1.6. programmers.stackexchange.com . (Hozzáférés: 2015. július 19.)
  14. To "new" or not to "new"…. (Hozzáférés: 2015. július 18.)
  15. How to write testable code. www.loosecouplings.com . (Hozzáférés: 2015. július 18.)
  16. Writing Clean, Testable Code. www.ethanresnick.com . (Hozzáférés: 2015. július 18.)
  17. Sironi, Giorgio: When to inject: the distinction between newables and injectables - Invisible to the eye. www.giorgiosironi.com . (Hozzáférés: 2015. július 18.)
  18. Inversion of Control vs Dependency Injection. stackoverflow.com . (Hozzáférés: 2015. augusztus 5.)
  19. What is the difference between Strategy pattern and Dependency Injection?. stackoverflow.com . (Hozzáférés: 2015. július 18.)
  20. Dependency Injection != using a DI container. www.loosecouplings.com . (Hozzáférés: 2015. július 18.)
  21. Black Sheep » DIY-DI » Print. blacksheep.parry.org . [2015. június 27-i dátummal az eredetiből archiválva]. (Hozzáférés: 2015. július 18.)
  22. a b The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 330. jcp.org . (Hozzáférés: 2015. július 18.)
  23. the urban canuk, eh: On Dependency Injection and Violating Encapsulation Concerns. www.bryancook.net . (Hozzáférés: 2015. július 18.)
  24. The Dependency Injection Design Pattern. msdn.microsoft.com . (Hozzáférés: 2015. július 18.)
  25. a b What are the downsides to using Dependency Injection?. stackoverflow.com . (Hozzáférés: 2015. július 18.)
  26. a b Dependency Injection Inversion - Clean Coder. sites.google.com . (Hozzáférés: 2015. július 18.)
  27. Decoupling Your Application From Your Dependency Injection Framework. InfoQ . (Hozzáférés: 2015. július 18.)
  28. The Dependency Injection design pattern - Structure and Collaboration. w3sDesign.com . (Hozzáférés: 2017. augusztus 12.)
  29. Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern - Forms of Dependency Injection. Martinfowler.com, 2004. január 23. (Hozzáférés: 2014. március 22.)
  30. Yan - Dependency Injection Types. Yan.codehaus.org. [2013. augusztus 18-i dátummal az eredetiből archiválva]. (Hozzáférés: 2013. december 11.)
  31. AccessibleObject (Java Platform SE 7). docs.oracle.com . (Hozzáférés: 2015. július 18.)
  32. Riehle, Dirk (2000), Framework Design: A Role Modeling Approach, Swiss Federal Institute of Technology, <http://www.riehle.org/computer-science/research/dissertation/diss-a4.pdf>
  33. Spring Tips: A POJO with annotations is not Plain. (Hozzáférés: 2015. július 18.)
  34. Annotations in POJO – a boon or a curse? | Techtracer. (Hozzáférés: 2015. július 18.)
  35. Pro Spring Dynamic Modules for OSGi Service Platforms. APress. (Hozzáférés: 2015. július 6.)