JNDI (Java Naming and Directory Interface) là một API quan trọng trong Java, cung cấp chức năng đặt tên và thư mục cho các ứng dụng Java. Nó được thiết kế đặc biệt cho nền tảng Java bằng mô hình đối tượng của Java. JNDI cho phép các ứng dụng Java lưu trữ và truy xuất các đối tượng Java theo tên, đồng thời cung cấp các phương thức để thực hiện các hoạt động thư mục tiêu chuẩn như liên kết thuộc tính và tìm kiếm đối tượng. Vậy JNDI là gì và tại sao nó lại quan trọng trong phát triển ứng dụng Java?
JNDI hoạt động độc lập với bất kỳ triển khai dịch vụ đặt tên hoặc thư mục cụ thể nào. Nó cho phép ứng dụng truy cập các dịch vụ thư mục, đặt tên và thư mục khác nhau thông qua một API chung. Các nhà cung cấp dịch vụ khác nhau có thể được “cắm” vào JNDI một cách dễ dàng, cho phép ứng dụng Java tận dụng thông tin từ nhiều nguồn như LDAP, DNS và NIS. Điều này giúp ứng dụng tích hợp tốt hơn với các hệ thống và phần mềm hiện có. Với JNDI, bạn có thể xây dựng các ứng dụng di động và mạnh mẽ, tận dụng mô hình đối tượng của Java và tích hợp tốt với môi trường triển khai.
Mục Lục
Kiến trúc của JNDI
Kiến trúc JNDI bao gồm hai thành phần chính: API (Application Programming Interface) và SPI (Service Provider Interface).
- API: Các ứng dụng Java sử dụng JNDI API để truy cập các chức năng đặt tên và thư mục. JNDI API định nghĩa các giao diện và lớp mà ứng dụng sử dụng để thực hiện các thao tác như tìm kiếm, liên kết và hủy liên kết các đối tượng.
- SPI: SPI cho phép các nhà cung cấp dịch vụ (providers) khác nhau tích hợp vào JNDI. Mỗi provider cung cấp một triển khai cụ thể của các giao diện JNDI, cho phép ứng dụng truy cập vào các dịch vụ đặt tên và thư mục khác nhau.
Kiến trúc JNDI
Một số JNDI provider phổ biến bao gồm:
- LDAP (Lightweight Directory Access Protocol): Dùng để truy cập các dịch vụ thư mục dựa trên giao thức LDAP.
- CORBA COS (Common Object Request Broker Architecture Common Object Services) name service: Dùng để truy cập các dịch vụ đặt tên CORBA.
- RMI Registry (Java Remote Method Invocation Registry): Dùng để truy cập registry RMI, cho phép các đối tượng Java từ xa được tìm thấy và gọi.
- DNS (Domain Name Service): Dùng để truy vấn thông tin từ hệ thống tên miền.
Các Trường Hợp Sử Dụng JNDI Phổ Biến
Một trong những trường hợp sử dụng JNDI phổ biến nhất là thiết lập connection pool (nhóm kết nối) cơ sở dữ liệu trên máy chủ ứng dụng Java EE. Bất kỳ ứng dụng nào được triển khai trên máy chủ đó đều có thể truy cập các kết nối mà nó cần bằng cách sử dụng một tên JNDI, ví dụ: java:comp/env/FooBarPool, mà không cần phải biết chi tiết về kết nối.
Việc sử dụng JNDI trong trường hợp này mang lại nhiều lợi ích:
- Tính linh hoạt: Khi ứng dụng di chuyển giữa các môi trường (dev -> int -> test -> prod), bạn có thể sử dụng cùng một tên JNDI trong mỗi môi trường và ẩn các chi tiết cấu hình cơ sở dữ liệu thực tế. Ứng dụng không cần phải thay đổi khi di chuyển giữa các môi trường.
- Bảo mật: Bạn có thể giảm thiểu số lượng người cần biết thông tin đăng nhập để truy cập cơ sở dữ liệu sản xuất. Chỉ máy chủ ứng dụng Java EE cần biết thông tin này nếu bạn sử dụng JNDI.
Giao diện Name trong JNDI
Giao diện Name cung cấp cơ chế quản lý tên và cú pháp cho JNDI. Thành phần đầu tiên trong chuỗi tên, đứng trước dấu /, đại diện cho global context (ngữ cảnh toàn cục), các thành phần phía sau đại diện cho các sub-context (ngữ cảnh con).
Ví dụ:
import javax.naming.CompositeName;
import javax.naming.InvalidNameException;
import javax.naming.Name;
import java.util.Enumeration;
class Main {
public static void main(String[] args) throws InvalidNameException {
Name objectName = new CompositeName("java:comp/env/jdbc");
Enumeration elements = objectName.getAll();
while(elements.hasMoreElements()) {
System.out.println(elements.nextElement());
}
}
}
Đoạn code trên sẽ in ra:
java:compenvjdbc
Giao diện Context trong JNDI
Giao diện Context chứa các thuộc tính của naming và directory service. Dưới đây là một ví dụ về cách sử dụng context trong Spring Framework:
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
builder.activate();
SimpleNamingContextBuilder trong Spring giúp tạo một JNDI provider và khởi chạy nó với NamingManager.
import org.springframework.jndi.JndiTemplate;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
JndiTemplate jndiTemplate = new JndiTemplate();
Context ctx = new InitialContext();
Binding và Lookup trong JNDI
Sau khi khởi tạo thành công SimpleNamingContextBuilder, bạn có thể sử dụng nó để lưu trữ (binding) một JDBC Datasource thông qua phương thức bind():
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.NamingException;
DataSource ds = new DriverManagerDataSource("jdbc:h2:mem:mydb");
ctx.bind("java:comp/env/jdbc/datasource", ds);
Sau khi đã binding Datasource thành công, bạn có thể truy xuất lại (lookup) nó bằng phương thức lookup():
import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.NamingException;
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
Alt: Mô tả quá trình binding (liên kết) một đối tượng với tên trong JNDI context và sau đó lookup (tìm kiếm) đối tượng đó bằng tên.
Kết luận
JNDI là một API mạnh mẽ cung cấp khả năng đặt tên và thư mục cho các ứng dụng Java. Nó cho phép ứng dụng truy cập các dịch vụ đặt tên và thư mục khác nhau một cách thống nhất, giúp tăng tính linh hoạt, khả năng bảo trì và bảo mật của ứng dụng. Việc hiểu rõ về JNDI và cách sử dụng nó là rất quan trọng đối với các nhà phát triển Java, đặc biệt là những người làm việc với các ứng dụng doanh nghiệp.
Tài liệu tham khảo:
