JNDI笔记(三)

原帖地址:http://blog.csdn.net/qhmao/archive/2008/10/19/3097753.aspx

 

在J2SE下使用JNDI下就显得困难一些,首先,我们没有单独的JNDI服务器可以用,JBoss提供了一个免费的JNP服务,通过配置可以作为 单独的JNDI服务器启用。不过这里就不这么麻烦了,如何使用JBOSS作为JNDI服务器,以后将单独撰文讲述,这里我使用sun提供的 com.sun.jndi.fscontext.RefFSContextFactory作为JNDI服务器,其实这是使用文件系统来存储JNDI对象。 至于如何存储后文还将专门描述。

为了在J2SE下使用JNDI,我们首先得到sun的网站上下载3个包,jndi.jar、fscontext.jar和providerutil.jar,前者提供了JNDI服务的接口,后两者是我们要使用的文件系统作为JNDI服务器的支持包。

使用RefFSContextFactory,要求绑定的对象必须实现javax.naming.Referencable接口,否则在绑定时将报如下错误:

Can only bind References or Referenceable objects

各个JDBC驱动提供商提供的DataSource类都实现了Referencable接口,可以直接使用。不过本着学习的态度,我还是在这里演示一下如何实现Referencable接口。

这个如何实现将在后文结合代码详细介绍。本例包括4个类,说明如下:

  • BindedClass:自定义的实现Referenceable接口的类
  • BindedClassFactory:工厂类,能够把一个Reference对象转换为BindedClass对象
  • Bind:测试类,用于在JNDI中绑定对象
  • Loopup:测试类,用于从JNDI中获取对象

3.1 BindedClass和BindedClassFactory

3.1.1 BindedClass

package  lld.test.jndi;

import  javax.naming.NamingException;
import  javax.naming.Reference;
import  javax.naming.Referenceable;
import  javax.naming.StringRefAddr;

public   class  BindedClass  implements  Referenceable 
... {
    
public  String value; 
    
    
public  BindedClass()
    
... {
    }

    
    @Override
    
public  Reference getReference()  throws  NamingException
    
... {
        Reference r 
=   new  Reference( this .getClass().getName(), BindedClassFactory. class .getName(),  null );
        r.add(
new  StringRefAddr( " value " this .getValue()));
        
return  r;
    }


    
public  String getValue()
    
... {
        
return  value;
    }


    
public   void  setValue(String value)
    
... {
        
this .value  =  value;
    }


}

 

3.1.2 BindedClassFactory

package  lld.test.jndi;

import  java.util.Hashtable;

import  javax.naming. * ;
import  javax.naming.spi. * ;

public   class  BindedClassFactory  implements  ObjectFactory
... {
    @Override
    
public  Object getObjectInstance(Object obj, Name name, Context nameCtx,
            Hashtable
<? ?>  environment)  throws  Exception
    
... {
        
if (obj  instanceof  Reference)
        
... {
            Reference ref 
=  (Reference)obj;
            String val 
=  (String)ref.get( " value " ).getContent();
            BindedClass o 
=   new  BindedClass();
            o.setValue(val);
            
return  o;
            
        }

        
return   null ;
    }

}

 

3.1.3 代码解释

Referenable接口只有一个方法,就是getReference(),返回一个Reference对象,BindedClass只设了一个 示例成员变量Value,存储一个字符串值,在创建Refernce对象时,要指定它引用的类名以及创建该类的工厂对象,JNDI Context在绑定该对象时就会将这些信息都存到文件中,将来从JNDI中取对象时可就全靠工厂对象根据文件中的内容重建BindedClass对象 了。我这里提前把绑定后生成的文件内容说一下,大家会更有一个直观的印象,其内容如下所示:

bind1/RefAddr/0/Type=value
bind1/ClassName=lld.test.jndi.BindedClass
bind1/RefAddr/0/Encoding=String
bind1/FactoryName=lld.test.jndi.BindedClassFactory
bind1/RefAddr/0/Content=abcdefg

大家看到了,前面在BindedClass.getReference()方法中使用了如下语句:

r.add(new StringRefAddr("value", this.getValue()));

就是定义要将这些信息存储到JNDI中呢,至于最后的“bind1/RefAddr/0/Content=abcdefg”,那是因为我在后面的示 例Bind.java中将其值设成了“abcdefg”而已,呵呵。而BindedClassFactory.getObjectInstance()方 法中

String val = (String)ref.get("value").getContent();

就是用来取到存储的值呢。

3.2 Bind.java

本例用来绑定一个BindedClass对象

package  lld.test.jndi;

import  java.util.Properties;

import  javax.naming.Context;
import  javax.naming.directory.DirContext;
import  javax.naming.directory.InitialDirContext;

public   class  Bind
... {
    
public   static   void  main(String[] args)  throws  Exception
    
... {
        Properties ps 
=   new  Properties();
        ps.setProperty(Context.INITIAL_CONTEXT_FACTORY, 
" com.sun.jndi.fscontext.RefFSContextFactory " );
        ps.setProperty(Context.PROVIDER_URL, 
" file:JNDI_REF " );
        DirContext ctx 
=   new  InitialDirContext(ps);
        String key 
=   " bind1 " ;

        BindedClass b 
=   new  BindedClass();
        b.setValue(
" abcdefg " );
        ctx.rebind(key, b);

        System.out.println(
" Binded successfully! " );
        ctx.close();
    }

}

 

3.3 Lookup.java

本例用来从JNDI中获取绑定的BindedClass对象

package  lld.test.jndi;

import  java.util.Properties;

import  javax.naming.Context;
import  javax.naming.directory.DirContext;
import  javax.naming.directory.InitialDirContext;

public   class  Lookup
... {
    
public   static   void  main(String[] args)  throws  Exception
    
... {
        Properties ps 
=   new  Properties();
        ps.setProperty(Context.INITIAL_CONTEXT_FACTORY, 
" com.sun.jndi.fscontext.RefFSContextFactory " );
        ps.setProperty(Context.PROVIDER_URL, 
" file:JNDI_REF " );
        DirContext ctx 
=   new  InitialDirContext(ps);
        String key 
=   " bind1 " ;
        BindedClass o 
=  (BindedClass)ctx.lookup(key);
        System.out.println(o.getValue());    
        
        ctx.close();
    }


}

你可能感兴趣的:(.net,jboss,jdbc,J2SE,sun)