Overzicht Java-naamgeving en directory-interface

1. Inleiding

De Java Naming and Directory Interface (JNDI) biedt consistent gebruik van naamgeving en / of directoryservices als een Java API. Deze interface kan worden gebruikt voor het binden van objecten, het opzoeken of opvragen van objecten, en het detecteren van wijzigingen aan dezelfde objecten.

Hoewel het gebruik van JNDI een gevarieerde lijst met ondersteunde naamgeving en directoryservices omvat, zullen we ons in deze tutorial concentreren op JDBC terwijl we de API van JNDI verkennen.

2. JNDI-beschrijving

Elk werk met JNDI vereist een begrip van de onderliggende dienst net zoals een toegankelijke implementatie. Een databaseverbindingsservice vraagt ​​bijvoorbeeld om specifieke eigenschappen en afhandeling van uitzonderingen.

Door de abstractie van JNDI wordt de verbindingsconfiguratie echter losgekoppeld van de applicatie.

Laten we onderzoeken Naam en Context, die de kernfunctionaliteit van JNDI bevatten.

2.1. Naam Koppel

Naam objectName = nieuwe CompositeName ("java: comp / env / jdbc");

De Naam interface biedt de mogelijkheid om de componentnamen en syntaxis voor JNDI-namen te beheren. Het eerste token van de string vertegenwoordigt de globale context, daarna vertegenwoordigt elke toegevoegde string de volgende subcontext:

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

Onze output ziet er als volgt uit:

java: comp env jdbc

Zoals we kunnen zien, / is het scheidingsteken voor Naam subcontexten. Laten we nu een subcontext toevoegen:

objectName.add ("voorbeeld");

Vervolgens testen we onze toevoeging:

assertEquals ("voorbeeld", objectName.get (objectName.size () - 1));

2.2. Context Koppel

Context bevat de eigenschappen voor de naamgeving en directoryservice. Laten we hier voor het gemak wat hulpcode van Spring gebruiken om een Context:

SimpleNamingContextBuilder builder = nieuwe SimpleNamingContextBuilder (); builder.activate ();

Lente SimpleNamingContextBuilder maakt een JNDI-provider aan en activeert vervolgens de builder met de NamingManager:

JndiTemplate jndiTemplate = nieuwe JndiTemplate (); ctx = (InitialContext) jndiTemplate.getContext ();

Tenslotte, JndiTemplate helpt ons toegang te krijgen tot het InitialContext.

3. JNDI-objectbinding en opzoeken

Nu we hebben gezien hoe te gebruiken Naam en Context, laten we JNDI gebruiken om een ​​JDBC op te slaan Databron:

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

3.1. JNDI-objecten binden

Laten we, aangezien we een context hebben, het object eraan binden:

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

In het algemeen zouden services een objectreferentie, geserialiseerde gegevens of attributen in een directorycontext moeten opslaan. Het hangt allemaal af van de behoeften van de applicatie.

Merk op dat het op deze manier gebruiken van JNDI minder gebruikelijk is. Doorgaans vormt JNDI een interface met gegevens die buiten de toepassingsruntime worden beheerd.

Als de applicatie echter al zijn Databron, is het misschien gemakkelijker om dat te bedraden met behulp van de veer. Als iets buiten onze applicatie daarentegen objecten in JNDI zou binden, dan zou de applicatie ze kunnen verbruiken.

3.2. JNDI-objecten opzoeken

Laten we onze opzoeken Databron:

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

En laten we dan testen om ervoor te zorgen Databron is zoals verwacht:

assertNotNull (ds.getConnection ());

4. Veelvoorkomende JNDI-uitzonderingen

Het werken met JNDI kan soms resulteren in runtime-uitzonderingen. Hier zijn enkele veelvoorkomende.

4.1. NameNotFoundException

ctx.lookup ("badJndiName");

Omdat deze naam in deze context niet gebonden is, zien we deze stacktracering:

javax.naming.NameNotFoundException: Naam [badJndiName] niet gebonden; 0 bindingen: [] op org.springframework.mock.jndi.SimpleNamingContext.lookup (SimpleNamingContext.java:140) op java.naming / javax.naming.InitialContext.lookup (InitialContext.java:409)

We moeten opmerken dat de stacktracering alle gebonden objecten bevat, wat handig is om op te sporen waarom de uitzondering is opgetreden.

4.2. NoInitialContextException

Elke interactie met de InitialContext kan gooien NoInitialContextException:

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

We moeten opmerken dat dit gebruik van JNDI geldig is, zoals we het eerder hebben gebruikt. Deze keer is er echter geen JNDI-contextprovider en wordt er een uitzondering gegenereerd:

javax.naming.NoInitialContextException: Noodzaak om de klassenaam op te geven in de omgeving of systeemeigenschap, of in een toepassingsbronbestand: java.naming.factory.initial op java.naming / javax.naming.spi.NamingManager.getInitialContext (NamingManager.java: 685)

5. Rol van JNDI in moderne applicatiearchitectuur

Terwijl JNDI speelt minder een rol in lichtgewicht, gecontaineriseerde Java-applicaties zoals Spring Boot zijn er andere toepassingen. Drie Java-technologieën die nog steeds JNDI gebruiken, zijn JDBC, EJB en JMS. Ze hebben allemaal een breed scala aan toepassingen in Java-bedrijfstoepassingen.

Een afzonderlijk DevOps-team kan bijvoorbeeld omgevingsvariabelen zoals gebruikersnaam en wachtwoord beheren voor een gevoelige databaseverbinding in alle omgevingen. Een JNDI-resource kan worden gemaakt in de webapplicatiecontainer, waarbij JNDI wordt gebruikt als een consistente abstractielaag die in alle omgevingen werkt.

Met deze opstelling kunnen ontwikkelaars een lokale definitie maken en beheren voor ontwikkelingsdoeleinden, terwijl ze via dezelfde JNDI-naam verbinding maken met gevoelige bronnen in een productieomgeving.

6. Conclusie

In deze tutorial zagen we het verbinden, binden en opzoeken van een object met behulp van de Java Naming and Directory Interface. We hebben ook gekeken naar de algemene uitzonderingen die door JNDI worden opgeworpen.

Ten slotte hebben we gekeken hoe JNDI past in de moderne applicatiearchitectuur.

Zoals altijd is de code beschikbaar op GitHub.