Ú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.