Útmutató a Google Guice-hoz
1. Bemutatkozás
Ez a cikk megvizsgálja a Google Guice alapjai. Megvizsgáljuk az alapvető függőségi injekció (DI) feladatok végrehajtásának megközelítéseit a Guice-ban.
Ezenkívül összehasonlítjuk és szembeállítjuk a Guice-megközelítést a kialakultabb DI-keretrendszerekkel, például a Spring and Contexts and Dependency Injection (CDI).
Ez a cikk feltételezi, hogy az olvasó megérti a függőségi injekció mintázatának alapjait.
2. Beállítás
A Google Guice használatához a Maven projektben a következő függőséget kell hozzáadnia a pom.xml:
com.google.inject guice 4.1.0
Itt található a Guice kiterjesztések gyűjteménye (ezekre egy kicsit később kitérünk), valamint harmadik féltől származó modulok a Guice képességeinek kibővítésére (főleg azáltal, hogy integráltabbá teszik a beépítettebb Java keretrendszereket).
3. Alapfüggőség injekció Guice-val
3.1. Mintaalkalmazásunk
Olyan szcenárióval fogunk dolgozni, ahol olyan osztályokat tervezünk, amelyek a helpdesk üzlet három kommunikációs eszközét támogatják: e-mail, SMS és IM.
Fontolja meg az osztályt:
public class Communication {@Inject private Logger logger; @ Fecskendezzen privát kommunikátor kommunikátort; nyilvános kommunikáció (logikai keepRecords) {if (keepRecords) {System.out.println ("Üzenetnaplózás engedélyezve"); }} nyilvános logikai sendMessage (karakterlánc üzenet) {return communicator.sendMessage (üzenet); }}
Ez Kommunikáció osztály a kommunikáció alapegysége. Ennek az osztálynak a példányát használjuk üzenetek küldésére a rendelkezésre álló kommunikációs csatornákon keresztül. A fentiek szerint Kommunikáció van egy Kommunikátor amelyet a tényleges üzenetátadáshoz használunk.
A Guice alapvető belépési pontja a Injektor:
public static void main (String [] args) {Injektorinjektor = Guice.createInjector (új BasicModule ()); Kommunikációs comms = injector.getInstance (Communication.class); }
Ez a fő módszer beolvassa a példányunkat Kommunikáció osztály. Bevezeti a Guice alapvető fogalmát is: a Modul (használatával BasicModule ebben a példában). A Modul a kötések meghatározásának alapvető egysége (vagy kábelezés, amint tavasszal ismert).
Guice kódelső megközelítést alkalmazott a függőség-injektáláshoz és -kezeléshez szóval nem sok XML-tel lesz dolgunk.
A fenti példában a Kommunikáció nevű szolgáltatás segítségével implicit módon injektálják éppen időben kötés, feltéve, hogy az osztályok rendelkeznek az alapértelmezett no-arg konstruktorral. Ez már a kezdetek óta jellemző a Guice-ban, és csak tavasszal érhető el a v4.3 óta.
3.2. Guice-kötések
A kötés Guice-hez, ahogy a kábelezés a Spring-hez. Kötéssel, te határozza meg, hogyan fogja Guice beadni a függőségeket osztályba.
A kötést a megvalósítás határozza meg com.google.inject.AbstractModule:
a public class BasicModule kiterjeszti az AbstractModule {@Orride védett void configure () {bind (Communicator.class) .to (DefaultCommunicatorImpl.class); }}
Ez a modul megvalósítás megadja, hogy a AlapértelmezettCommunicatorImpl be kell adni, bárhol a Kommunikátor változó található.
Ennek a mechanizmusnak egy másik megtestesülése a megkötésnek nevezték. Vegye figyelembe a következő változó deklarációt:
@ Inject @Named ("DefaultCommunicator") Communicator kommunikátor;
Ehhez a következő kötelező meghatározást fogjuk megadni:
@Orride védett void configure () {bind (Communicator.class) .annotatedWith (Név.név ("DefaultCommunicator"))) .to (Communicator.class); }
Ez az összerendelés a Kommunikátor a - vel annotált változóhoz @Named (“DefaultCommunicator”) annotáció.
Észre fogja venni a @ Injekció és @Nevezett úgy tűnik, hogy a jelölések a Jakarta EE CDI-jének kölcsönjegyzetei, és azok is. Ők a com.google.inject. * csomag - vigyázzon, hogy az IDE használatakor a megfelelő csomagból importáljon.
Tipp: Míg csak azt mondtuk, hogy használja a Guice által biztosított @ Injekció és @Nevezett, érdemes megjegyezni, hogy a Guice valóban támogatást nyújt a javax.inject.Inject és javax.inject.Named, a többi Jakarta EE annotáció között.
Olyan függőséget is injektálhat, amely nem rendelkezik alapértelmezett no-arg konstruktorral konstruktor kötés:
a public class BasicModule kiterjeszti az AbstractModule {@Orride védett void configure () {bind (Boolean.class) .toInstance (true); kötés (Communication.class) .toConstructor (Communication.class.getConstructor (Boolean.TYPE)); }
A fenti kódrészlet a Kommunikáció a konstruktort használva, amely a logikai érv. Mi szállítjuk a igaz érv a kivitelező számára meghatározó an céltalan kötés a Logikai osztály.
Ez céltalan kötés lelkesen látják el minden konstruktorral a kötésben, amely elfogadja a logikai paraméter. Ezzel a megközelítéssel a Kommunikáció beadják.
A konstruktor-specifikus kötés másik megközelítése a példánykötés, ahol egy példányt közvetlenül a kötésben adunk meg:
a public class BasicModule kiterjeszti az AbstractModule {@Orride védett void configure () {bind (Communication.class) .toInstance (új Communication (true)); }}
Ez az összerendelés a Kommunikáció osztály bárhol a Kommunikáció változót deklaráljuk.
Ebben az esetben azonban az osztály függőségi fája nem lesz automatikusan bekötve. Korlátoznia kell ennek a módnak a használatát, ha nincs szükség nagy inicializálásra vagy függőségi injekcióra.
4. A függőségi injekció típusai
A Guice támogatja a szokásos típusú injekciókat, amelyekre a DI mintával számíthattak volna. Ban,-ben Kommunikátor osztályban különböző típusú injekciókat kell beadnunk CommunicationMode.
4.1. Terepi injekció
@ Inject @Named ("SMSComms") CommunicationMode smsComms;
Használja az opcionális opciót @Nevezett jelölés minősítőként a név alapján célzott injekció megvalósításához
4.2. Módszer injekció
Itt egy szetter módszert használunk az injekció eléréséhez:
@ Inject public void setEmailCommunicator (@Név ("EmailComms") CommunicationMode emailComms) {this.emailComms = emailComms; }
4.3. Konstruktor befecskendezése
Függőségeket is beadhat egy konstruktor segítségével:
@ Nyilvános kommunikáció beadása (@Név ("IMComms") CommunicationMode imComms) {this.imComms = imComms; }
4.4. Implicit injekciók
Guice implicit módon injektál néhány általános célú komponenst, például a Injektor és a java.util.Loggertöbbek között. Észre fogja venni, hogy a mintákon keresztül naplózókat használunk, de tényleges kötést nem talál számukra.
5. Átvizsgálás Guice-ban
A Guice támogatja azokat a hatóköröket és hatókörmechanizmusokat, amelyeket más DI keretrendszerekben már megszokhattunk. A Guice alapértelmezés szerint egy meghatározott függőség új példányát adja meg.
5.1. Szingli
Injekciózzunk egy szingulettet az alkalmazásunkba:
kötés (Communicator.class) .annotatedWith (Név.nevezett ("AnotherCommunicator")) .to (Communicator.class) .in (Scopes.SINGLETON);
A itt: (Hatályok.SINGLETON) meghatározza, hogy bármelyik Kommunikátor mező a @Named („AnotherCommunicator”) bead egy szingulettet. Ez a szingli alapból lustán indul.
5.2. Vágyakozó Singleton
Most adjunk be egy lelkes szingulettet:
bind (Communicator.class) .annotatedWith (Név.neves ("AnotherCommunicator"))) .to (Communicator.class) .asEagerSingleton ();
A asEagerSingleton () A hívás a szingulettet lelkesen példázza.
E két hatókör mellett a Guice támogatja az egyedi hatóköröket, valamint a csak az internetet @RequestScoped és @SessionScoped feljegyzéseket a Jakarta EE bocsátotta rendelkezésre (ezeknek a feljegyzéseknek nincsenek Guice által szállított változatai).
6. Aspektorientált programozás a Guice-ban
A Guice megfelel az AOPAlliance szempontorientált programozásra vonatkozó előírásainak. Csak négy lépésben valósíthatjuk meg a lényegnaplózó elfogót, amelyet a példánkban az üzenetküldés nyomon követésére használunk.
1. lépés - Az AOPAlliance megvalósítása MethodInterceptor:
public class MessageLogger megvalósítja a MethodInterceptor {@Inject Logger logger programot; @ A nyilvános objektumhívás felülbírálása (MethodInvocation invokáció) dobható {Object [] objectArray = invocation.getArguments (); for (Object object: objectArray) {logger.info ("Üzenet küldése:" + object.toString ()); } return invocation.proceed (); }}
2. lépés - Adjon meg egy egyszerű Java-jelölést:
@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface MessageSentLoggable {}
3. lépés - Határozz meg egy kötést egy pároshoz:
Matcher egy Guice osztály, amelyet használunk, megadja azokat az összetevőket, amelyekre az AOP kommentárunk vonatkozni fog. Ebben az esetben azt szeretnénk, ha az annotáció a CommunicationMode:
public class AOPModule kiterjeszti az AbstractModule {@Orride védett void configure () {bindInterceptor (Matchers.any (), Matchers.annotatedWith (MessageSentLoggable.class), új MessageLogger ()); }}
Meghatároztuk a Matcher itt alkalmazzák a mi MessageLogger elfogó Bármi osztály, annak megvan MessageSentLoggable módszereire alkalmazott annotáció.
4. lépés - Alkalmazza a kommentárokat a kommunikációs módunkra, és töltse be a modulunkat
@Override @MessageSentLoggable nyilvános logikai sendMessage (karakterlánc-üzenet) {logger.info ("SMS-üzenet elküldve"); return true; } public static void main (String [] args) {Injector injector = Guice.createInjector (new BasicModule (), new AOPModule ()); Kommunikációs comms = injector.getInstance (Communication.class); }
7. Következtetés
Miután megnézte a Guice alapvető funkcionalitását, láthatjuk, honnan származik az inspiráció a Guice számára Springből.
A JSR-330 támogatásával együtt a Guice injekció-központú DI keretrendszerré kíván válni (míg a Spring egy teljes ökoszisztémát biztosít a programozás kényelméhez, nem feltétlenül csak a DI-hez), olyan fejlesztők számára, akik rugalmasságot akarnak.
A Guice emellett rendkívül kibővíthető, lehetővé téve a programozók számára, hogy hordozható beépülő modulokat írjanak, amelyek a keret rugalmas és kreatív használatát eredményezik. Ez kiegészíti azt a kiterjedt integrációt, amelyet a Guice már a legnépszerűbb keretrendszerek és platformok számára biztosít, mint például a Servlet, a JSF, a JPA és az OSGi, hogy csak néhányat említsünk.
Az oktatóanyagban használt összes forráskód megtalálható a GitHub projektben.