JavaRush /จาวาบล็อก /Random-TH /การใช้ JNDI ใน Java
Анзор Кармов
ระดับ
Санкт-Петербург

การใช้ JNDI ใน Java

เผยแพร่ในกลุ่ม
สวัสดี! วันนี้เราจะมาแนะนำให้คุณรู้จักกับ JNDI เรามาดูกันว่ามันคืออะไร เหตุใดจึงจำเป็น มันทำงานอย่างไร และเราจะทำงานกับมันได้อย่างไร จากนั้นเราจะเขียนการทดสอบหน่วย Spring Boot ซึ่งภายในเราจะเล่นกับ JNDI นี้ การใช้ JNDI ใน Java - 1

การแนะนำ. บริการตั้งชื่อและไดเร็กทอรี

ก่อนที่จะเจาะลึก JNDI มาทำความเข้าใจก่อนว่าบริการการตั้งชื่อและไดเร็กทอรีคืออะไร ตัวอย่างที่ชัดเจนที่สุดของบริการดังกล่าวคือระบบไฟล์บนพีซี แล็ปท็อป หรือสมาร์ทโฟน ระบบไฟล์จัดการไฟล์ (ผิดปกติพอสมควร) ไฟล์ในระบบดังกล่าวจะถูกจัดกลุ่มไว้ในโครงสร้างแบบต้นไม้ แต่ละไฟล์มีชื่อเต็มไม่ซ้ำกัน เช่น C:\windows\notepad.exe โปรดทราบ: ชื่อไฟล์แบบเต็มคือพาธจากจุดต้นทาง (ไดรฟ์ C) ไปยังไฟล์นั้นเอง (notepad.exe) โหนดกลางในห่วงโซ่ดังกล่าวคือไดเร็กทอรี (ไดเร็กทอรี windows) ไฟล์ภายในไดเร็กทอรีมีคุณสมบัติ ตัวอย่างเช่น "ซ่อน" "อ่านอย่างเดียว" ฯลฯ คำอธิบายโดยละเอียดเกี่ยวกับสิ่งง่าย ๆ เช่นระบบไฟล์จะช่วยให้เข้าใจคำจำกัดความของการตั้งชื่อและบริการไดเรกทอรีได้ดีขึ้น ดังนั้นบริการชื่อและไดเร็กทอรีจึงเป็นระบบที่จัดการการแมปชื่อหลายชื่อกับออบเจ็กต์จำนวนมาก ในระบบไฟล์ของเรา เราโต้ตอบกับชื่อไฟล์ที่ซ่อนอ็อบเจ็กต์ ซึ่งเป็นไฟล์ในรูปแบบต่างๆ ในบริการการตั้งชื่อและไดเร็กทอรี ออบเจ็กต์ที่มีชื่อจะถูกจัดระเบียบเป็นโครงสร้างแบบต้นไม้ และวัตถุไดเรกทอรีมีคุณสมบัติ อีกตัวอย่างหนึ่งของบริการชื่อและไดเร็กทอรีคือ DNS (Domain Name System) ระบบนี้จัดการการจับคู่ระหว่างชื่อโดเมนที่มนุษย์สามารถอ่านได้ (เช่น https://javarush.com/) และที่อยู่ IP ที่เครื่องอ่านได้ (เช่น 18.196.51.113) นอกจาก DNS และระบบไฟล์แล้ว ยังมีบริการอื่นๆ อีกมากมาย เช่น:

เจเอ็นดีไอ

JNDI หรือ Java Naming and Directory Interface เป็น Java API สำหรับการเข้าถึงบริการการตั้งชื่อและไดเรกทอรี JNDI เป็น API ที่ให้กลไกแบบเดียวกันสำหรับโปรแกรม Java เพื่อโต้ตอบกับบริการการตั้งชื่อและไดเร็กทอรีต่างๆ ภายใต้ฝากระโปรง การรวมระหว่าง JNDI และบริการใดๆ ที่กำหนดสามารถทำได้สำเร็จโดยใช้ Service Provider Interface (SPI) SPI ช่วยให้บริการการตั้งชื่อและไดเร็กทอรีต่างๆ สามารถเชื่อมต่อได้อย่างโปร่งใส ช่วยให้แอปพลิเคชัน Java ใช้ JNDI API เพื่อเข้าถึงบริการที่เชื่อมต่อได้ รูปด้านล่างแสดงให้เห็นถึงสถาปัตยกรรม JNDI: การใช้ JNDI ใน Java - 2

ที่มา: บทช่วยสอน Oracle Java

เจเอ็นดีไอ. ความหมายเป็นคำง่ายๆ

คำถามหลักคือ: ทำไมเราถึงต้องการ JNDI? จำเป็นต้องใช้ JNDI เพื่อให้เราสามารถรับอ็อบเจ็กต์ Java จาก "การลงทะเบียน" ของอ็อบเจ็กต์บางส่วนจากโค้ด Java โดยใช้ชื่อของอ็อบเจ็กต์ที่เชื่อมโยงกับอ็อบเจ็กต์นี้ ลองแยกข้อความข้างต้นออกเป็นวิทยานิพนธ์เพื่อไม่ให้เราสับสนกับคำซ้ำๆ มากมาย:
  1. ท้ายที่สุดเราจำเป็นต้องได้รับวัตถุ Java
  2. เราจะได้รับวัตถุนี้จากรีจิสทรีบางส่วน
  3. มีวัตถุมากมายในรีจิสทรีนี้
  4. แต่ละออบเจ็กต์ในรีจิสทรีนี้มีชื่อเฉพาะ
  5. ในการรับออบเจ็กต์จากรีจิสตรี เราต้องส่งชื่อในคำขอของเรา ราวกับจะพูดว่า: "โปรดให้สิ่งที่คุณมีภายใต้ชื่อเช่นนี้แก่ฉันด้วย"
  6. เราไม่เพียงแต่สามารถอ่านออบเจ็กต์ตามชื่อจากรีจิสตรีได้เท่านั้น แต่ยังบันทึกออบเจ็กต์ในรีจิสตรีนี้ภายใต้ชื่อบางชื่อได้ด้วย
ดังนั้นเราจึงมีรีจิสทรีหรือพื้นที่จัดเก็บอ็อบเจ็กต์หรือแผนผัง JNDI ต่อไป เรามาลองทำความเข้าใจความหมายของ JNDI กันโดยใช้ตัวอย่าง เป็นที่น่าสังเกตว่า JNDI ส่วนใหญ่ใช้ในการพัฒนาองค์กร และแอปพลิเคชันดังกล่าวทำงานได้ภายในแอปพลิเคชันเซิร์ฟเวอร์บางตัว เซิร์ฟเวอร์นี้อาจเป็น Java EE Application Server บางตัว หรือคอนเทนเนอร์เซิร์ฟเล็ต เช่น Tomcat หรือคอนเทนเนอร์อื่นๆ รีจิสทรีอ็อบเจ็กต์เอง นั่นคือ JNDI Tree มักจะอยู่ภายในแอปพลิเคชันเซิร์ฟเวอร์นี้ อย่างหลังไม่จำเป็นเสมอไป (คุณสามารถมีต้นไม้ชนิดนี้ได้ในพื้นที่) แต่เป็นเรื่องปกติมากที่สุด JNDI Tree สามารถจัดการได้โดยบุคคลพิเศษ (ผู้ดูแลระบบหรือผู้เชี่ยวชาญ DevOps) ซึ่งจะ "บันทึกในรีจิสทรี" ออบเจ็กต์พร้อมชื่อของพวกเขา เมื่อแอปพลิเคชันของเราและ JNDI Tree อยู่ร่วมกันภายในคอนเทนเนอร์เดียวกัน เราสามารถเข้าถึงอ็อบเจ็กต์ Java ใดๆ ที่จัดเก็บไว้ในรีจิสทรีดังกล่าวได้อย่างง่ายดาย นอกจากนี้ รีจิสทรีและแอปพลิเคชันของเรายังอยู่ในคอนเทนเนอร์ที่แตกต่างกันและแม้แต่ในเครื่องจริงที่แตกต่างกัน JNDI ยังอนุญาตให้คุณเข้าถึงวัตถุ Java จากระยะไกลได้ กรณีทั่วไป ผู้ดูแลระบบเซิร์ฟเวอร์ Java EE จะวางอ็อบเจ็กต์ไว้ในรีจิสตรีที่เก็บข้อมูลที่จำเป็นสำหรับการเชื่อมต่อกับฐานข้อมูล ดังนั้น ในการทำงานกับฐานข้อมูล เราจะขอออบเจ็กต์ที่ต้องการจากแผนผัง JNDI และทำงานกับมัน มันสะดวกสบายมาก ความสะดวกสบายยังอยู่ที่ความจริงที่ว่าในการพัฒนาองค์กรนั้นมีสภาพแวดล้อมที่แตกต่างกัน มีเซิร์ฟเวอร์ที่ใช้งานจริงและมีเซิร์ฟเวอร์ทดสอบ (และมักจะมีเซิร์ฟเวอร์ทดสอบมากกว่า 1 แห่ง) จากนั้น ด้วยการวางออบเจ็กต์สำหรับเชื่อมต่อกับฐานข้อมูลบนแต่ละเซิร์ฟเวอร์ภายใน JNDI และใช้ออบเจ็กต์นี้ภายในแอปพลิเคชันของเรา เราจะไม่ต้องเปลี่ยนแปลงอะไรเมื่อปรับใช้แอปพลิเคชันของเราจากเซิร์ฟเวอร์หนึ่ง (ทดสอบ ปล่อย) ไปยังอีกเซิร์ฟเวอร์หนึ่ง จะมีการเข้าถึงฐานข้อมูลทุกที่ แน่นอนว่าตัวอย่างนี้ค่อนข้างเรียบง่าย แต่ฉันหวังว่ามันจะช่วยให้คุณเข้าใจได้ดีขึ้นว่าทำไมต้องใช้ JNDI ต่อไป เราจะมาทำความรู้จักกับ JNDI ในภาษา Java ให้ละเอียดยิ่งขึ้น พร้อมองค์ประกอบบางประการของการโจมตี

JNDI API

JNDI มีให้ภายในแพลตฟอร์ม Java SE หากต้องการใช้ JNDI คุณต้องนำเข้าคลาส JNDI รวมถึงผู้ให้บริการตั้งแต่หนึ่งรายขึ้นไปเพื่อเข้าถึงบริการการตั้งชื่อและไดเร็กทอรี JDK รวมถึงผู้ให้บริการสำหรับบริการต่อไปนี้:
  • โปรโตคอลการเข้าถึงไดเรกทอรีน้ำหนักเบา (LDAP);
  • สถาปัตยกรรมนายหน้าขอวัตถุทั่วไป (CORBA);
  • บริการชื่อ Common Object Services (COS)
  • รีจิสทรีการร้องขอวิธีการระยะไกล Java (RMI)
  • บริการชื่อโดเมน (DNS)
รหัส JNDI API แบ่งออกเป็นหลายแพ็คเกจ:
  • javax.การตั้งชื่อ;
  • javax.naming.directory;
  • javax.naming.ldap;
  • javax.naming.event;
  • javax.naming.spi
เราจะเริ่มต้นการแนะนำ JNDI ด้วยอินเทอร์เฟซสองแบบ - ชื่อและบริบท ซึ่งมีฟังก์ชันการทำงานของ JNDI ที่สำคัญ

ชื่ออินเทอร์เฟซ

อินเทอร์เฟซชื่อช่วยให้คุณควบคุมชื่อส่วนประกอบตลอดจนไวยากรณ์การตั้งชื่อ JNDI ใน JNDI การดำเนินการชื่อและไดเร็กทอรีทั้งหมดจะดำเนินการโดยสัมพันธ์กับบริบท ไม่มีรากที่แน่นอน ดังนั้น JNDI จึงกำหนด InitialContext ซึ่งจัดเตรียมจุดเริ่มต้นสำหรับการตั้งชื่อและการดำเนินการไดเร็กทอรี เมื่อเข้าถึงบริบทเริ่มต้นแล้ว จะสามารถใช้เพื่อค้นหาอ็อบเจ็กต์และบริบทอื่นๆ ได้
Name objectName = new CompositeName("java:comp/env/jdbc");
ในโค้ดด้านบน เราได้กำหนดชื่อที่วัตถุบางอย่างตั้งอยู่ (อาจไม่พบตำแหน่งนี้ แต่เรากำลังนับอยู่) เป้าหมายสุดท้ายของเราคือการได้รับการอ้างอิงถึงวัตถุนี้และใช้ในโปรแกรมของเรา ดังนั้นชื่อประกอบด้วยหลายส่วน (หรือโทเค็น) คั่นด้วยเครื่องหมายทับ โทเค็นดังกล่าวเรียกว่าบริบท บริบทแรกเป็นเพียงบริบท บริบทต่อมาทั้งหมดเป็นบริบทย่อย (ต่อไปนี้จะเรียกว่าบริบทย่อย) บริบทจะเข้าใจได้ง่ายขึ้นหากคุณคิดว่าบริบทเหล่านั้นคล้ายคลึงกับไดเร็กทอรีหรือไดเร็กทอรี หรือเป็นเพียงโฟลเดอร์ทั่วไป บริบทรูทคือโฟลเดอร์รูท บริบทย่อยเป็นโฟลเดอร์ย่อย เราสามารถดูส่วนประกอบทั้งหมด (บริบทและบริบทย่อย) ของชื่อที่กำหนดได้โดยการรันโค้ดต่อไปนี้:
Enumeration<String> elements = objectName.getAll();
while(elements.hasMoreElements()) {
  System.out.println(elements.nextElement());
}
ผลลัพธ์จะเป็นดังนี้:

java:comp
env
jdbc
ผลลัพธ์แสดงให้เห็นว่าโทเค็นในชื่อถูกแยกออกจากกันด้วยเครื่องหมายทับ (แต่เราพูดถึงสิ่งนี้) โทเค็นชื่อแต่ละรายการมีดัชนีของตัวเอง การจัดทำดัชนีโทเค็นเริ่มต้นที่ 0 บริบทรูทมีดัชนีเป็นศูนย์ บริบทถัดไปมีดัชนี 1 บริบทถัดไป 2 เป็นต้น เราสามารถรับชื่อบริบทย่อยได้จากดัชนี:
System.out.println(objectName.get(1)); // -> env
นอกจากนี้เรายังสามารถเพิ่มโทเค็นเพิ่มเติมได้ (ไม่ว่าจะที่ส่วนท้ายหรือที่ตำแหน่งเฉพาะในดัชนี):
objectName.add("sub-context"); // Добавит sub-context в конец
objectName.add(0, "context"); // Добавит context в налачо
รายการวิธีการทั้งหมดสามารถพบได้ในเอกสารอย่างเป็นทางการ

บริบทอินเทอร์เฟซ

อินเทอร์เฟซนี้ประกอบด้วยชุดของค่าคงที่สำหรับการเริ่มต้นบริบท เช่นเดียวกับชุดของวิธีการสำหรับการสร้างและการลบบริบท การผูกวัตถุเข้ากับชื่อ และการค้นหาและการดึงข้อมูลวัตถุ มาดูการดำเนินการบางอย่างที่ดำเนินการโดยใช้อินเทอร์เฟซนี้ การดำเนินการที่พบบ่อยที่สุดคือการค้นหาวัตถุตามชื่อ ทำได้โดยใช้วิธีการ:
  • Object lookup(String name)
  • Object lookup(Name name)
การผูกวัตถุกับชื่อทำได้โดยใช้วิธีการbind:
  • void bind(Name name, Object obj)
  • void bind(String name, Object obj)
ทั้งสองวิธีจะผูกชื่อกับวัตถุObject การดำเนินการผกผันของการเชื่อมโยง - ปลดวัตถุออกจากชื่อจะดำเนินการโดยใช้วิธีการunbind:
  • void unbind(Name name)
  • void unbind(String name)
รายการวิธีการทั้งหมดมีอยู่ในเว็บไซต์เอกสารอย่างเป็นทางการ

บริบทเริ่มต้น

InitialContextเป็นคลาสที่แสดงถึงองค์ประกอบรูทของแผนผัง JNDI และใช้Context. คุณต้องค้นหาอ็อบเจ็กต์ตามชื่อภายในแผนผัง JNDI ที่สัมพันธ์กับโหนดใดโหนดหนึ่ง โหนดรูทของทรีสามารถทำหน้าที่เป็นโหนดดังกล่าวInitialContextได้ กรณีการใช้งานทั่วไปสำหรับ JNDI คือ:
  • รับInitialContext.
  • ใช้InitialContextเพื่อดึงวัตถุตามชื่อจากแผนผัง JNDI
InitialContextมีหลายวิธีที่จะ ได้รับมัน ทุกอย่างขึ้นอยู่กับสภาพแวดล้อมที่โปรแกรม Java ตั้งอยู่ ตัวอย่างเช่น หากโปรแกรม Java และแผนผัง JNDI ทำงานภายในแอปพลิเคชันเซิร์ฟเวอร์เดียวกันInitialContextการรับสิ่งนี้ค่อนข้างง่าย:
InitialContext context = new InitialContext();
หากไม่เป็นเช่นนั้น การรับบริบทก็จะยากขึ้นเล็กน้อย บางครั้งจำเป็นต้องส่งรายการคุณสมบัติสภาพแวดล้อมเพื่อเริ่มต้นบริบท:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
    "com.sun.jndi.fscontext.RefFSContextFactory");

Context ctx = new InitialContext(env);
ตัวอย่างข้างต้นแสดงให้เห็นหนึ่งในวิธีที่เป็นไปได้ในการเริ่มต้นบริบท และไม่มีการโหลดความหมายอื่นๆ ไม่จำเป็นต้องเจาะลึกโค้ดโดยละเอียด

ตัวอย่างการใช้ JNDI ในการทดสอบหน่วย SpringBoot

ข้างต้น เราได้กล่าวไว้ว่าเพื่อให้ JNDI โต้ตอบกับบริการตั้งชื่อและไดเร็กทอรีได้ จำเป็นต้องมี SPI (Service Provider Interface) อยู่ในมือ โดยจะได้รับความช่วยเหลือในการผสานรวมระหว่าง Java และบริการตั้งชื่อ JDK มาตรฐานมาพร้อมกับ SPI ต่างๆ มากมาย (เราระบุไว้ข้างต้น) ซึ่งแต่ละ SPI นั้นไม่ค่อยมีประโยชน์สำหรับการสาธิต การเพิ่มแอปพลิเคชัน JNDI และ Java ภายในคอนเทนเนอร์นั้นค่อนข้างน่าสนใจ อย่างไรก็ตาม ผู้เขียนบทความนี้เป็นคนเกียจคร้าน ดังนั้นเพื่อสาธิตวิธีการทำงานของ JNDI เขาเลือกเส้นทางที่มีการต่อต้านน้อยที่สุด: รัน JNDI ภายในการทดสอบหน่วยแอปพลิเคชัน SpringBoot และเข้าถึงบริบท JNDI โดยใช้แฮ็กเล็กๆ จาก Spring Framework ดังนั้นแผนของเรา:
  • มาเขียนโปรเจ็กต์ Spring Boot ที่ว่างเปล่ากัน
  • มาสร้างการทดสอบหน่วยภายในโปรเจ็กต์นี้กันดีกว่า
  • ภายในการทดสอบ เราจะสาธิตการทำงานกับ JNDI:
    • เข้าถึงบริบท
    • ผูก (ผูก) วัตถุบางอย่างภายใต้ชื่อบางอย่างใน JNDI;
    • รับวัตถุตามชื่อ (ค้นหา);
    • ตรวจสอบว่าวัตถุไม่เป็นโมฆะ
มาเริ่มกันตามลำดับ ไฟล์->ใหม่->โครงการ... การใช้ JNDI ใน Java - 3จากนั้นเลือก รายการ Spring Initializr : การใช้ JNDI ใน Java - 4กรอกข้อมูลเมตาเกี่ยวกับโครงการ: การใช้ JNDI ใน Java - 5จากนั้นเลือกส่วนประกอบ Spring Framework ที่ต้องการ เราจะผูกวัตถุ DataSource บางตัว ดังนั้นเราจึงต้องการส่วนประกอบเพื่อทำงานกับฐานข้อมูล:
  • JDBC API;
  • ฐานข้อมูล H2 D
การใช้ JNDI ใน Java - 6มากำหนดตำแหน่งในระบบไฟล์กันเถอะ: การใช้ JNDI ใน Java - 7และโปรเจ็กต์ก็ถูกสร้างขึ้น อันที่จริง การทดสอบหนึ่งหน่วยถูกสร้างขึ้นโดยอัตโนมัติสำหรับเรา ซึ่งเราจะใช้เพื่อวัตถุประสงค์ในการสาธิต ด้านล่างนี้เป็นโครงสร้างโครงการและการทดสอบที่เราต้องการ: การใช้ JNDI ใน Java - 8มาเริ่มเขียนโค้ดภายในการทดสอบ contextLoads กัน แฮ็คเล็กๆ จาก Spring ที่กล่าวถึงข้างต้นคือคลาสSimpleNamingContextBuilder. คลาสนี้ออกแบบมาเพื่อยกระดับ JNDI ภายในการทดสอบหน่วยหรือแอปพลิเคชันแบบสแตนด์อโลนได้อย่างง่ายดาย มาเขียนโค้ดเพื่อรับบริบท:
final SimpleNamingContextBuilder simpleNamingContextBuilder
       = new SimpleNamingContextBuilder();
simpleNamingContextBuilder.activate();

final InitialContext context = new InitialContext();
โค้ดสองบรรทัดแรกจะช่วยให้เราสามารถเริ่มต้นบริบท JNDI ได้อย่างง่ายดายในภายหลัง หากไม่มีสิ่งเหล่านี้InitialContextจะมีข้อยกเว้นเกิดขึ้นเมื่อสร้างอินสแตนซ์javax.naming.NoInitialContextException: ข้อสงวนสิทธิ์ คลาสนี้SimpleNamingContextBuilderเป็นคลาสที่เลิกใช้แล้ว และตัวอย่างนี้มีวัตถุประสงค์เพื่อแสดงให้เห็นว่าคุณสามารถทำงานร่วมกับ JNDI ได้อย่างไร สิ่งเหล่านี้ไม่ใช่แนวทางปฏิบัติที่ดีที่สุดสำหรับการใช้ JNDI ในการทดสอบหน่วย สิ่งนี้สามารถกล่าวได้ว่าเป็นไม้ค้ำยันสำหรับการสร้างบริบทและสาธิตการเชื่อมโยงและการดึงวัตถุจาก JNDI เมื่อได้รับบริบทแล้ว เราสามารถแยกวัตถุออกจากบริบทหรือค้นหาวัตถุในบริบทได้ ยังไม่มีวัตถุใน JNDI ดังนั้นจึงสมเหตุสมผลที่จะวางบางสิ่งไว้ที่นั่น ตัวอย่างเช่น, DriverManagerDataSource:
context.bind("java:comp/env/jdbc/datasource", new DriverManagerDataSource("jdbc:h2:mem:mydb"));
ในบรรทัด นี้ เราได้ผูกคลาสอ็อบเจ็กต์DriverManagerDataSourceเข้ากับชื่อ java:comp/env/jdbc/datasourceต่อไปเราสามารถรับวัตถุจากบริบทตามชื่อได้ เราไม่มีทางเลือกอื่นนอกจากต้องได้วัตถุที่เราเพิ่งใส่ไป เนื่องจากไม่มีวัตถุอื่นในบริบท =(
final DataSource ds = (DataSource) context.lookup("java:comp/env/jdbc/datasource");
ตอนนี้เรามาตรวจสอบว่าแหล่งข้อมูลของเรามีการเชื่อมต่อ (การเชื่อมต่อ การเชื่อมต่อ หรือการเชื่อมต่อเป็นคลาส Java ที่ออกแบบมาเพื่อทำงานกับฐานข้อมูล):
assert ds.getConnection() != null;
System.out.println(ds.getConnection());
หากเราทำทุกอย่างถูกต้อง ผลลัพธ์จะเป็นดังนี้:

conn1: url=jdbc:h2:mem:mydb user=
ควรบอกว่าโค้ดบางบรรทัดอาจมีข้อยกเว้น บรรทัดต่อไปนี้ถูกโยนjavax.naming.NamingException:
  • simpleNamingContextBuilder.activate()
  • new InitialContext()
  • context.bind(...)
  • context.lookup(...)
และเมื่อทำงานกับคลาสDataSourceก็สามารถโยนทิ้งjava.sql.SQLExceptionได้ ในเรื่องนี้ มีความจำเป็นต้องรันโค้ดภายในบล็อกtry-catchหรือระบุในลายเซ็นของหน่วยทดสอบว่าสามารถส่งข้อยกเว้นได้ นี่คือรหัสที่สมบูรณ์ของคลาสการทดสอบ:
@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();
        }
    }
}
หลังจากรันการทดสอบ คุณจะเห็นบันทึกต่อไปนี้:

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=

บทสรุป

วันนี้เรามาดู JNDI เราได้เรียนรู้ว่าบริการการตั้งชื่อและไดเร็กทอรีคืออะไร และ JNDI คือ Java API ที่ช่วยให้คุณสามารถโต้ตอบกับบริการต่างๆ จากโปรแกรม Java ได้อย่างสม่ำเสมอ กล่าวคือ ด้วยความช่วยเหลือของ JNDI เราสามารถบันทึกวัตถุในแผนผัง JNDI ภายใต้ชื่อที่กำหนด และรับวัตถุเดียวกันเหล่านี้ตามชื่อ เป็นงานพิเศษ คุณสามารถรันตัวอย่างวิธีการทำงานของ JNDI ได้ ผูกวัตถุอื่นเข้ากับบริบท และจากนั้น อ่านวัตถุนี้ตามชื่อ
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION