JavaRush /Java Blog /Random-TK /Java-da JNDI ulanmak
Анзор Кармов
Dereje
Санкт-Петербург

Java-da JNDI ulanmak

Toparda çap edildi
Salam! Bu gün sizi JNDI bilen tanyşdyrarys. Onuň nämedigini, näme üçin zerurdygyny, nähili işleýändigini, onuň bilen nädip işleşip biljekdigimizi öwreneliň. Soň bolsa, “JNDI” bilen oýnajak “Bahar Boot” bölüminiň synagyny ýazarys. Java-da JNDI ulanmak - 1

Giriş At bermek we katalog hyzmatlary

JNDI-e girmezden ozal, atlandyryş we katalog hyzmatlarynyň nämedigine düşüneliň. Şeýle hyzmatyň iň aýdyň mysaly islendik kompýuterde, noutbukda ýa-da smartfonda faýl ulgamydyr. Faýl ulgamy faýllary dolandyrýar (geň galdyryjy). Şeýle ulgamlardaky faýllar agaç gurluşyna bölünýär. Her faýlyň özboluşly doly ady bar, mysal üçin: C: \ windows \ notepad.exe. Üns beriň: faýlyň doly ady käbir kök nokadyndan (C sürüjisi) faýlyň özüne (notepad.exe) barýan ýol. Şeýle zynjyrdaky aralyk düwünler kataloglardyr (windows katalogy). Kataloglaryň içindäki faýllaryň atributlary bar. Mysal üçin, “Gizlin”, “Diňe okaň” we ş.m. Faýl ulgamy ýaly ýönekeý bir zadyň jikme-jik beýany, atlandyryş we katalog hyzmatlarynyň kesgitlemesine has gowy düşünmäge kömek eder. Şeýlelik bilen, at we katalog hyzmaty köp atlaryň köp obýektlere kartalaşdyrylmagyny dolandyrýan ulgamdyr. Faýl ulgamymyzda obýektleri gizleýän faýl atlary - dürli formatdaky faýllaryň özleri bilen aragatnaşyk saklaýarys. Atlandyrmak we katalog hyzmatynda atlandyrylan obýektler agaç gurluşyna bölünýär. Katalog obýektleriniň atributlary bar. Adyň we katalog hyzmatynyň başga bir mysaly DNS (Domain Name System). Bu ulgam adam tarapyndan okalýan domen atlarynyň (mysal üçin, https://javarush.com/) we maşyn okalýan IP adresleriniň (mysal üçin, 18.196.51.113) arasyndaky kartalaşdyryşy dolandyrýar. DNS we faýl ulgamlaryndan başga-da başga hyzmatlar köp, meselem:

JNDI

JNDI, ýa-da Java atlandyryş we katalog interfeýsi, atlandyrmak we katalog hyzmatlaryna girmek üçin Java API. JNDI, Java programmasynyň dürli atlandyryş we katalog hyzmatlary bilen täsirleşmegi üçin birmeňzeş mehanizmi üpjün edýän API. Baş kapotyň aşagynda JNDI bilen islendik hyzmatyň arasynda integrasiýa Hyzmat üpjün edijiniň interfeýsi (SPI) arkaly amala aşyrylýar. SPI dürli atlandyryş we katalog hyzmatlaryny aç-açan birleşdirmäge mümkinçilik berýär, bu Java programmasyna birikdirilen hyzmatlara girmek üçin JNDI API ulanmaga mümkinçilik berýär. Aşakdaky surat JNDI arhitekturasyny görkezýär: Java-da JNDI ulanmak - 2

Çeşme: Oracle Java Tutorials

JNDI. Simpleönekeý sözleriň manysy

Esasy sorag: JNDI näme üçin gerek? JNDI zerur, bu obýekt bilen baglanyşykly obýektiň ady bilen Java kodundan obýektleriň käbir “Hasaba alynmagy” -dan Java obýektini alyp bileris. Gaýtalanýan sözleriň köplügi bizi bulaşdyrmazlygy üçin ýokardaky beýany tezislere böleliň:
  1. Netijede, Java obýektini almaly.
  2. Bu obýekti käbir reýestrlerden alarys.
  3. Bu reýestrde bir topar obýekt bar.
  4. Bu reýestrdäki her bir obýektiň özboluşly ady bar.
  5. Hasaba alyş sanawyndan bir zat almak üçin haýyşymyzda bir at bermeli. Diýjek bolýan ýaly: "Maňa şeýle we şeýle at bilen eýe bolan zadyňyzy beriň".
  6. Reýestrden diňe atlary bilen obýektleri okap bilmeris, eýsem bu reýestrdäki obýektleri belli atlar bilen saklap bileris (nämüçindir ol ýerde gutarýar).
Şeýlelikde, bizde haýsydyr bir registr, ýa-da obýekt saklamak ýa-da JNDI agajy bar. Ondan soň, mysal ulanyp, JNDI-iň manysyna düşünmäge synanyşalyň. JNDI-iň köplenç kärhanany ösdürmekde ulanylýandygyny bellemelidiris. Şeýle programmalar käbir programma serweriniň içinde işleýär. Bu serwer käbir Java EE Programma Serweri, ýa-da Tomcat ýaly serwer konteýner ýa-da başga bir konteýner bolup biler. Obýekt registriniň özi, ýagny JNDI agajy, adatça bu programma serweriniň içinde ýerleşýär. Ikinjisi hemişe zerur däl (ýerli görnüşde şeýle agaç bolup biler), ýöne iň adaty. JNDI agajy, atlary bilen "reýestrde ýatda saklar" ýörite adam (ulgam dolandyryjysy ýa-da DevOps hünärmeni) tarapyndan dolandyrylyp bilner. Haçan-da programmamyz we JNDI agajy şol bir konteýneriň içinde ýerleşende, şeýle reýestrde saklanýan islendik Java obýektine aňsatlyk bilen girip bileris. Mundan başga-da, reýestr we amalymyz dürli gaplarda we hatda dürli fiziki maşynlarda hem bolup biler. JNDI hatda Java obýektlerine uzakdan girmäge mümkinçilik berýär. Adaty ýagdaý. Java EE serwer dolandyryjysy, maglumatlar bazasyna birikmek üçin zerur maglumatlary saklaýan sanawda bir obýekt ýerleşdirýär. Şoňa laýyklykda maglumatlar binýady bilen işlemek üçin JNDI agajyndan zerur obýekti sorarys we onuň bilen işleşeris. Bu örän amatly. Amatlylyk, kärhanany ösdürmekde dürli gurşawyň bolmagy bilen baglanyşyklydyr. Önümçilik serwerleri bar we synag serwerleri bar (we köplenç 1-den gowrak synag serweri bar). Soňra, JNDI-iň içindäki her serwerde maglumat bazasyna birikmek üçin bir obýekt ýerleşdirip we programmamyzyň içinde bu obýekti ulanyp, programmamyzy bir serwerden (synag, goýbermek) beýlekisine ýerleşdirenimizde hiç zady üýtgetmeli bolmaz. Maglumat bazasyna hemme ýerde girip bolar. Mysal, elbetde, birneme ýönekeýleşdirildi, ýöne JNDI-iň näme üçin zerurdygyna has gowy düşünmäge kömek eder diýip umyt edýärin. Ondan soň, hüjümiň käbir elementleri bilen Java-da JNDI bilen has ýakyndan tanşarys.

JNDI API

JNDI Java SE platformasynda üpjün edilýär. JNDI ulanmak üçin JNDI synplaryny, şeýle hem at we katalog hyzmatlaryna girmek üçin bir ýa-da birnäçe hyzmat üpjün edijisini import etmeli. JDK aşakdaky hyzmatlar üçin hyzmat üpjün edijileri öz içine alýar:
  • Directoryeňil kataloglara giriş protokoly (LDAP);
  • Umumy obýekt haýyşy dellal arhitekturasy (CORBA);
  • Umumy obýekt hyzmatlary (COS) at hyzmaty;
  • Java uzakdan usul çagyryş (RMI) sanawy;
  • Domen ady hyzmaty (DNS).
JNDI API kody birnäçe paketlere bölünýär:
  • javax.naming;
  • javax.naming.directory;
  • javax.naming.ldap;
  • javax.naming.event;
  • javax.naming.spi.
JNDI bilen tanyşlygymyzy iki interfeýs bilen başlarys - esasy JNDI funksiýasyny öz içine alýan Ady we Konteksti

Interfeýsiň ady

“Name” interfeýsi komponent atlaryny, şeýle hem JNDI atlandyryş sintaksisini dolandyrmaga mümkinçilik berýär. JNDI-de ähli at we katalog amallary kontekste görä ýerine ýetirilýär. Mutlak kök ýok. Şonuň üçin JNDI atlandyrmak we katalog amallary üçin başlangyç nokady üpjün edýän “InitialContext” -i kesgitleýär. Başlangyç kontekste girensoň, obýektleri we beýleki mazmuny gözlemek üçin ulanylyp bilner.
Name objectName = new CompositeName("java:comp/env/jdbc");
Aboveokardaky kodda, haýsydyr bir obýektiň ýerleşýän käbir adyny kesgitledik (ol ýerleşmän biler, ýöne biz oňa bil baglaýarys). Iň soňky maksadymyz, bu obýekte salgylanma almak we ony programmamyzda ulanmak. Şeýlelik bilen, at çyzgy bilen bölünen birnäçe bölekden (ýa-da belliklerden) ybaratdyr. Şeýle belliklere kontekst diýilýär. Birinjisi ýönekeý kontekst, soňrakylaryň hemmesi kiçi kontekstdir (mundan beýläk kiçi kontekst diýilýär). Mazmuny, kataloglara ýa-da kataloglara ýa-da diňe adaty bukjalara meňzeş hasaplasaňyz düşünmek has aňsat. Kök mazmuny kök bukjadyr. Subkontekst kiçi bukjadyr. Aşakdaky kody işledip, belli bir atyň ähli komponentlerini (kontekst we kiçi tekstleri) görüp bileris:
Enumeration<String> elements = objectName.getAll();
while(elements.hasMoreElements()) {
  System.out.println(elements.nextElement());
}
Çykyş aşakdaky ýaly bolar:

java:comp
env
jdbc
Çykyş, adyndaky bellikleriň biri-birinden çyzgy bilen bölünýändigini görkezýär (ýöne, muny belledik). Her bir at nyşanynyň öz görkezijisi bar. Token indeksirlemesi 0-dan başlaýar. Kök kontekstinde nol indeks, indiki kontekstde 1 indeks, indiki 2 we ş.m. bar. Subkontekstiň adyny indeks boýunça alyp bileris:
System.out.println(objectName.get(1)); // -> env
Şeýle hem goşmaça bellikler goşup bileris (ahyrynda ýa-da indeksdäki belli bir ýerde):
objectName.add("sub-context"); // Добавит sub-context в конец
objectName.add(0, "context"); // Добавит context в налачо
Usullaryň doly sanawyny resmi resminamalarda tapyp bilersiňiz .

Interfeýsiň mazmuny

Bu interfeýsde konteksti başlatmak üçin yzygiderlilikler toplumy, şeýle hem kontekstleri döretmek we pozmak, obýektleri bir ada baglamak, obýektleri gözlemek we gözlemek usullary bar. Geliň, bu interfeýsi ulanyp ýerine ýetirilýän käbir amallara seredeliň. Iň ýaýran hereket, bir zady at bilen gözlemekdir. Bu usullaryň kömegi bilen amala aşyrylýar:
  • Object lookup(String name)
  • Object lookup(Name name)
Obýektiň adyna daňmak usullary ulanyp amala aşyrylýar bind:
  • void bind(Name name, Object obj)
  • void bind(String name, Object obj)
Iki usul hem adyň adyny obýekt bilen baglanyşdyrar. Object Baglamagyň ters işi - bir obýektiň adyndan aýrylmagy, usullar arkaly amala aşyrylýar unbind:
  • void unbind(Name name)
  • void unbind(String name)
Usullaryň doly sanawy resmi resminamalar web sahypasynda elýeterlidir .

Başlangyç kontekst

InitialContextJNDI agajynyň kök elementini görkezýän we ýerine ýetirýän synpdyr Context. Belli bir düwün bilen deňeşdirilende JNDI agajynyň içindäki zatlary gözlemeli. Agajyň kök düwünleri şeýle düwün bolup hyzmat edip biler InitialContext. JNDI üçin adaty ulanylyş hadysasy:
  • Al InitialContext.
  • InitialContextJNDI agajyndan obýektleri almak üçin ulanyň .
Ony almagyň birnäçe usuly bar InitialContext. Bularyň hemmesi Java programmasynyň ýerleşýän gurşawyna baglydyr. Mysal üçin, bir programma serweriniň içinde Java programmasy we JNDI agajy işleýän bolsa, InitialContextalmak gaty ýönekeý:
InitialContext context = new InitialContext();
Eger beýle bolmasa, kontekst almak birneme kynlaşýar. Konteksti başlamak üçin käwagt daşky gurşaw aýratynlyklarynyň sanawyny geçmeli bolýar:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
    "com.sun.jndi.fscontext.RefFSContextFactory");

Context ctx = new InitialContext(env);
Aboveokardaky mysal, konteksti başlatmagyň mümkin usullaryndan birini görkezýär we başga semantik ýük götermeýär. Koda jikme-jik girmegiň zerurlygy ýok.

“SpringBoot” birlik synagynyň içinde JNDI ulanmagyň mysaly

Oveokarda, JNDI-iň at dakmak we katalog hyzmaty bilen täsirleşmegi üçin elinde SPI (Hyzmat üpjün edijiniň interfeýsi) bolmalydygyny, munuň kömegi bilen Java bilen atlandyryş hyzmatynyň arasynda integrasiýa amala aşyryljakdygyny aýtdyk. Adaty JDK birnäçe dürli SPI bilen gelýär (ýokarda sanadyk), bularyň her biri görkeziş maksatlary üçin kän bir gyzyklanmaýar. Konteýneriň içinde JNDI we Java programmasyny ösdürmek birneme gyzykly. Şeýle-de bolsa, bu makalanyň awtory ýalta adam, şonuň üçin JNDI-iň işleýşini görkezmek üçin iň az garşylyk ýoluny saýlady: SpringBoot amaly bölüminiň synagynda JNDI işlediň we Bahar çarçuwasyndan kiçijik bir hak ulanyp JNDI kontekstine giriň. Şeýlelikde, meýilnamamyz:
  • Boş Bahar Boot taslamasyny ýazalyň.
  • Geliň, bu taslamanyň içinde birlik synagyny döredeliň.
  • Synagyň içinde JNDI bilen işleýändigimizi görkezeris:
    • kontekste girmek;
    • JNDI-de haýsydyr bir at bilen haýsydyr bir obýekti baglamak (daňmak);
    • obýektiň adyny almak (gözlemek);
    • Obýektiň ýokdugyny barlalyň.
Geliň, tertip bilen başlalyň. Faýl-> Täze-> Taslama ... Java-da JNDI ulanmak - 3 Soňra, “Bahar Initializr” elementini saýlaň : Java-da JNDI ulanmak - 4Taslama barada meta-maglumaty dolduryň: Java-da JNDI ulanmak - 5Soňra zerur bahar çarçuwasynyň böleklerini saýlaň. Käbir DataSource obýektlerini baglanyşdyrarys, şonuň üçin maglumatlar bazasy bilen işlemek üçin komponentler gerek:
  • JDBC API;
  • H2 maglumat bazasy.
Java-da JNDI ulanmak - 6Faýl ulgamynyň ýerleşýän ýerini kesgitläliň: Java-da JNDI ulanmak - 7Taslama döredildi. Aslynda, görkeziş maksatly ulanjak bir bölüm synagy awtomatiki usulda döredildi. Aşakda taslama gurluşy we bize zerur synag: Java-da JNDI ulanmak - 8Geliň, kontekstLoads synagynyň içinde kod ýazyp başlalyň. Aboveokarda ara alnyp maslahatlaşylan Bahardan gelen kiçijik hack SimpleNamingContextBuilder. Bu synp JNDI-ni birlik synaglarynyň ýa-da özbaşdak programmalaryň içinde aňsatlyk bilen ýokarlandyrmak üçin döredildi. Konteksti almak üçin kod ýazalyň:
final SimpleNamingContextBuilder simpleNamingContextBuilder
       = new SimpleNamingContextBuilder();
simpleNamingContextBuilder.activate();

final InitialContext context = new InitialContext();
Ilkinji iki setir kod, soň JNDI kontekstini aňsatlyk bilen başlamaga mümkinçilik berer. Olar bolmasa, InitialContextmysal döredilende kadadan çykma bolar : javax.naming.NoInitialContextException. Düşündiriş. Bu synp SimpleNamingContextBuilderköne synp. Bu mysal, JNDI bilen nädip işleşip boljakdygyny görkezmek üçin niýetlenendir. Bölüm synaglarynyň içinde JNDI ulanmak üçin bu iň oňat tejribe däl. Kontekst gurmak we JNDI-den baglanyşyk we zatlary almak üçin taýak diýmek bolar. Kontekst alanymyzdan, ondan obýektleri çykaryp ýa-da kontekstdäki zatlary gözläp bileris. JNDI-de entek obýekt ýok, şonuň üçin ol ýere bir zat goýmak mantykly bolardy. Mysal üçin DriverManagerDataSource:
context.bind("java:comp/env/jdbc/datasource", new DriverManagerDataSource("jdbc:h2:mem:mydb"));
DriverManagerDataSourceBu setirde synp obýektini ada bagladyk java:comp/env/jdbc/datasource. Ondan soň obýekti kontekstden ady boýunça alyp bileris. Diňe goýan obýektimizi almakdan başga alajymyz ýok, sebäbi kontekstde başga zatlar ýok = (
final DataSource ds = (DataSource) context.lookup("java:comp/env/jdbc/datasource");
Indi “DataSource” -yň baglanyşygynyň bardygyny barlalyň (birikme, birikme ýa-da birikme maglumatlar bazasy bilen işlemek üçin döredilen Java synpy):
assert ds.getConnection() != null;
System.out.println(ds.getConnection());
Hemme zady dogry ýerine ýetiren bolsak, çykyş şeýle bolar:

conn1: url=jdbc:h2:mem:mydb user=
Kodlaryň käbir setirlerinde kadadan çykmalar bolup biljekdigini aýtmak gerek. Aşakdaky setirler atylýar javax.naming.NamingException:
  • simpleNamingContextBuilder.activate()
  • new InitialContext()
  • context.bind(...)
  • context.lookup(...)
Bir synp bilen işlän wagtyňyz bolsa DataSourcezyňyp bolýar java.sql.SQLException. try-catchŞunuň bilen baglylykda, kody blokuň içinde ýerine ýetirmek ýa-da kadadan çykmalary atyp biljekdigini synag bölüminiň golunda görkezmek zerurdyr . Synag synpynyň doly kody:
@SpringBootTest
class JndiExampleApplicationTests {

    @Test
    void contextLoads() {
        try {
            final SimpleNamingContextBuilder simpleNamingContextBuilder
                    = new SimpleNamingContextBuilder();
            simpleNamingContextBuilder.activate();

            final InitialContext context = new InitialContext();

            context.bind("java:comp/env/jdbc/datasource", new DriverManagerDataSource("jdbc:h2:mem:mydb"));

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

            assert ds.getConnection() != null;
            System.out.println(ds.getConnection());

        } catch (SQLException | NamingException e) {
            e.printStackTrace();
        }
    }
}
Synag geçirilenden soň aşakdaky ýazgylary görüp bilersiňiz:

o.s.m.jndi.SimpleNamingContextBuilder    : Activating simple JNDI environment
o.s.mock.jndi.SimpleNamingContext        : Static JNDI binding: [java:comp/env/jdbc/datasource] = [org.springframework.jdbc.datasource.DriverManagerDataSource@4925f4f5]
conn1: url=jdbc:h2:mem:mydb user=

Netije

Bu gün JNDI-e göz aýladyk. Adyň we katalog hyzmatlarynyň nämedigini we JNDI-iň Java programmasyndaky dürli hyzmatlar bilen birmeňzeş aragatnaşyk saklamaga mümkinçilik berýän Java API bolandygyny öwrendik. .Agny, JNDI-iň kömegi bilen JNDI agajyndaky zatlary belli bir at bilen ýazyp bileris we şol bir zatlary at bilen alyp bileris. Bonus meselesi hökmünde JNDI-iň işleýşine mysal edip bilersiňiz. Başga bir obýekti kontekste baglaň we soňra bu obýektiň adyny okaň.
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION