关于JNDI介绍

我们分两个部分来研究JNDI,首先了解一些JNDI的框架,然后再写一个类似helloword实例并分析源码
一: JNDI架构及接口:
(1):架构图
这里写图片描述
JNDI主要分三个部分,其中JNDi API提供给应用端查找调用服务接口,JNDI SPI提供给供应商实现。
(2):JNDI程序包
    1、Javax.naming:包含了访问命名服务的类和接口。例如,它定义了Context接口,这是命名服务执行查询的入口。
    2、Javax.naming.directory:对命名包的扩充,提供了访问目录服务的类和接口。例如,它为属性增加了新的类,提供了表示目录上下文的DirContext接口,定义了检查和更新目录对象的属性的方法。
    3、Javax.naming.event:提供了对访问命名和目录服务时的事件通知的支持。例如,定义了NamingEvent类,这个类用来表示命名/目录服务产生的事件,定义了侦听NamingEvents的NamingListener接口。
    4、Javax.naming.ldap:这个包提供了对LDAP 版本3扩充的操作和控制的支持,通用包javax.naming.directory没有包含这些操作和控制。
    5、Javax.naming.spi:这个包提供了一个方法,通过javax.naming和有关包动态增加对访问命名和目录服务的支持。这个包是为有兴趣创建服务提供者的开发者提供的。
二:JNDI的使用示例
(1)服务提供商实现JNDI SPI提供服务
spi接口:InitialContextFactory

    1:实现Context

public class AnimalContext extends InitialContext{
private static HashMap<String, Object> map = new HashMap<String, Object>();

public AnimalContext() throws NamingException {
    super();
}

public void unbind(String name) throws NamingException {
    map.remove(name);
}

public void bind(String name, Object o) throws NamingException{
    map.put(name, o);
}

public Object lookup(String name) throws NamingException{
    return map.get(name);
}
}

   2:实现contextFactory

public class AnimalContextFactory implements InitialContextFactory{

/**
 * environment是应用端提供的包括服务厂商所需要的参数
 */
@Override
public Context getInitialContext(Hashtable<?, ?> environment)
        throws NamingException {
    // TODO Auto-generated method stub
    AnimalContext context = new AnimalContext();
    context.bind("cat", new Cat("redCat"));
    context.bind("dog", new Dog("yellowDog"));
    context.bind("crow", new Craw("milkCraw"));
    return new AnimalContext();
}

}

    3: 对象接口

/**
* 动物
*/
public interface Animal {
public String eat(String food);
}
/**
* 猫
*/
public class Cat implements Animal{

private String name;

public Cat(String name){
this.name = name;
}

public String eat(String food) {
return this.name + ” eat ” + food;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
/**
* 牛
*/
public class Craw implements Animal{

private String name;

public Craw(String name){
this.name = name;
}

public String eat(String food) {
return this.name + ” eat ” + food;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
/**
* 狗
*/
public class Dog implements Animal{

private String name;

public Dog(String name){
this.name = name;
}

public String eat(String food) {
return this.name + ” craw ” + food;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

(2)应用端通过JNDI API调用服务

public class CosumeClient{

public static void main(String[] args) {
    try {
        Hashtable<String, Object> env = new Hashtable<String, Object>();
        env.put("java.naming.factory.initial", "jndi.context.AnimalContextFactory");
        Context clientContext = new InitialContext(env);
        System.out.println(((Animal)clientContext.lookup("cat")).eat("fish"));
    } catch (NamingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

执行结果:redCat eat fish。

通过这个示例就对JNDI有一些了解了。

那么下面我们来研究一下JNDI源码

(3)JNDI源码分析

客户端调用执行:

Context clientContext = new InitialContext(env);

时后面运行的代码是 NamingManager 的getInitialContext(Hashtable<?,?> env) 方法里面的这段代码

 public static Context getInitialContext(Hashtable<?,?> env)
throws NamingException {
InitialContextFactory factory; 

InitialContextFactoryBuilder builder = getInitialContextFactoryBuilder();
if (builder == null) {
    // No factory installed, use property
    // Get initial context factory class name

    String className = env != null ?
        (String)env.get(Context.INITIAL_CONTEXT_FACTORY) : null;
    if (className == null) {
    NoInitialContextException ne = new NoInitialContextException(
        "Need to specify class name in environment or system " +
        "property, or as an applet parameter, or in an " +
        "application resource file:  " + 
        Context.INITIAL_CONTEXT_FACTORY);
    throw ne;
    }

    try {
    factory = (InitialContextFactory)
        helper.loadClass(className).newInstance();
    } catch(Exception e) {
    NoInitialContextException ne = 
        new NoInitialContextException(
        "Cannot instantiate class: " + className);
    ne.setRootCause(e);
    throw ne;
    }
} else {
    factory = builder.createInitialContextFactory(env);
}

return factory.getInitialContext(env);
}

将应用端传递的jndi.context.AnimalContextFactory通过反射加载进来并创建initialContext。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值