Prehľad Java Naming a adresárového rozhrania

1. Úvod

Rozhranie Java Naming and Directory Interface (JNDI) poskytuje dôsledné používanie pomenovacích a / alebo adresárových služieb ako rozhrania Java API. Toto rozhranie možno použiť na viazanie objektov, vyhľadávanie alebo dopytovanie objektov, ako aj na zisťovanie zmien na rovnakých objektoch.

Zatiaľ čo použitie JNDI obsahuje rôznorodý zoznam podporovaných pomenovacích a adresárových služieb, v tomto tutoriáli sa zameriame na JDBC pri skúmaní API JNDI.

2. Popis JNDI

Akákoľvek práca s JNDI si vyžaduje porozumenie základnej služby ako aj prístupná implementácia. Napríklad služba databázového pripojenia vyžaduje špecifické vlastnosti a spracovanie výnimiek.

Abstrakcia JNDI však oddeľuje konfiguráciu pripojenia od aplikácie.

Poďme preskúmať názov a Kontext, ktoré obsahujú základnú funkcionalitu JNDI.

2.1. názov Rozhranie

Názov objectName = nový CompositeName ("java: comp / env / jdbc");

The názov rozhranie poskytuje schopnosť spravovať názvy komponentov a syntax pre názvy JNDI. Prvý token reťazca predstavuje globálny kontext, potom každý pridaný reťazec predstavuje nasledujúci podkontext:

Enumeration elements = objectName.getAll (); while (elements.hasMoreElements ()) {System.out.println (elements.nextElement ()); }

Náš výstup vyzerá takto:

java: comp env jdbc

Ako vidíme, / je oddeľovač pre názov podkontexty. Teraz pridajme podkontext:

objectName.add ("príklad");

Potom otestujeme náš prídavok:

assertEquals ("príklad", objectName.get (objectName.size () - 1));

2.2. Kontext Rozhranie

Kontext obsahuje vlastnosti pomenovacej a adresárovej služby. Tu poďme na uľahčenie zostavenia a použiť nejaký pomocný kód z jari Kontext:

SimpleNamingContextBuilder builder = nový SimpleNamingContextBuilder (); builder.activate ();

Jarné SimpleNamingContextBuilder vytvorí poskytovateľa JNDI a potom aktivuje staviteľa pomocou NamingManager:

JndiTemplate jndiTemplate = nový JndiTemplate (); ctx = (InitialContext) jndiTemplate.getContext ();

Nakoniec JndiTemplate pomáha nám získať prístup k InitialContext.

3. Viazanie a vyhľadávanie objektov JNDI

Teraz, keď sme videli, ako sa používa názov a Kontext, použijeme JNDI na uloženie JDBC Dátový zdroj:

ds = new DriverManagerDataSource ("jdbc: h2: mem: mydb");

3.1. Viazanie objektov JNDI

Pretože máme kontext, spojme s ním objekt:

ctx.bind ("java: comp / env / jdbc / datasource", ds);

Služby by vo všeobecnosti mali ukladať referencie na objekty, serializované údaje alebo atribúty v kontexte adresára. Všetko závisí od potrieb aplikácie.

Upozorňujeme, že použitie JNDI týmto spôsobom je menej bežné. Spravidla JNDI rozhranie s údajmi, ktoré sa spravujú mimo runtime aplikácie.

Ak však aplikácia už dokáže vytvoriť alebo nájsť svoju Dátový zdroj, mohlo by byť jednoduchšie prepojiť to pomocou pružiny. Naopak, ak niečo mimo našich aplikácií viaže objekty v JNDI, potom by ich aplikácia mohla spotrebovať.

3.2. Vyhľadanie objektov JNDI

Pozrime sa na naše Dátový zdroj:

DataSource ds = (DataSource) ctx.lookup ("java: comp / env / jdbc / datasource");

A potom to otestujme Dátový zdroj je podľa očakávania:

assertNotNull (ds.getConnection ());

4. Bežné výnimky JNDI

Práca s JNDI môže niekedy viesť k výnimkám za behu. Tu uvádzam niekoľko bežných.

4.1. NameNotFoundException

ctx.lookup ("badJndiName");

Pretože tento názov nie je v tomto kontexte viazaný, vidíme toto trasovanie zásobníka:

javax.naming.NameNotFoundException: Meno [badJndiName] nie je viazané; 0 väzieb: [] na org.springframework.mock.jndi.SimpleNamingContext.lookup (SimpleNamingContext.java:140) na java.naming / javax.naming.InitialContext.lookup (InitialContext.java:409)

Mali by sme poznamenať, že sledovanie zásobníka obsahuje všetky viazané objekty, čo je užitočné na sledovanie toho, prečo došlo k výnimke.

4.2. NoInitialContextException

Akákoľvek interakcia s InitialContext môže hádzať NoInitialContextException:

assertThrows (NoInitialContextException.class, () -> {JndiTemplate jndiTemplate = new JndiTemplate (); InitialContext ctx = (InitialContext) jndiTemplate.getContext (); ctx.lookup ("java: comp / env / jdbc)" .printStackTrace ();

Mali by sme poznamenať, že toto použitie JNDI je platné, pretože sme ho používali už skôr. Tentokrát však neexistuje žiadny poskytovateľ kontextu JNDI a bude vyvolaná výnimka:

javax.naming.NoInitialContextException: Je potrebné zadať názov triedy v prostredí alebo vlastnosti systému alebo v súbore prostriedkov aplikácie: java.naming.factory.initial na adrese java.naming / javax.naming.spi.NamingManager.getInitialContext (NamingManager.java: 685)

5. Úloha JNDI v modernej aplikačnej architektúre

Zatiaľ čo JNDI hrá v ľahkých kontajnerovaných aplikáciách Java menšiu úlohu napríklad Spring Boot, existujú aj ďalšie použitia. Tri technológie Java, ktoré stále používajú JNDI, sú JDBC, EJB a JMS. Všetky majú širokú škálu použitia v rámci podnikových aplikácií Java.

Napríklad samostatný tím DevOps môže spravovať premenné prostredia, ako sú používateľské meno a heslo pre citlivé pripojenie k databáze vo všetkých prostrediach. Prostriedok JNDI možno vytvoriť v kontajneri webových aplikácií, pričom JNDI sa môže použiť ako vrstva konzistentnej abstrakcie, ktorá funguje vo všetkých prostrediach.

Toto nastavenie umožňuje vývojárom vytvárať a ovládať lokálnu definíciu pre vývojové účely a súčasne sa pripájať k citlivým zdrojom v produkčnom prostredí pomocou rovnakého názvu JNDI.

6. Záver

V tomto tutoriáli sme videli pripojenie, väzbu a vyhľadanie objektu pomocou rozhrania Java Naming and Directory Interface. Pozreli sme sa tiež na bežné výnimky udelené JNDI.

Nakoniec sme sa pozreli na to, ako JNDI zapadá do modernej aplikačnej architektúry.

Ako vždy, kód je k dispozícii na GitHub.