jndi step by step (6) 高级应用之 环境属性

1、环境属性

    在之前的文档里,我们已经学会如何去初始化一个内容上下文,例如:

java 代码
  1. Hashtable env = new Hashtable();   
  2. env.put(Context.INITIAL_CONTEXT_FACTORY,    
  3.     "com.sun.jndi.ldap.LdapCtxFactory");   
  4. env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");   
  5.   
  6. Context ctx = new InitialContext(env);  

 

    这个例子中的 Hashtable,就是一个环境属性,或者简单的说是“环境”。
    这个章节里,我们要介绍的就是这个“环境属性”,看看他们是如何发挥作用的,以及如何使用的等等。
   
    JNDI其实只是一个接口,为了访问一个命名/目录服务,你必须依赖特定的SPI。这就需要进行一些配置,
    你得告诉JNDI,你需要的SPI是什么。
   
    下面是一些不同种类的环境属性:
   
    a> 标准的
    b> 描述服务的
    c> 描述特性的
    d> 描述提供者的。
   
    下面是标准的环境属性:

   

 

    1.1、环境属性
   
    配置环境属性可以通过两种方式:一个是把一个Hashtable传递给InitialContext的构造函数,另一个
    是用一个 .properties 文件。
    一些JNDI的环境属性还可以通过系统变量或者Applet参数来设置。
   
    1.1.1、应用程序资源文件(.properties文件)
   
    你可以在 .properties文件 里指定JNDI的配置。这个文件的名字应该是 jndi.properties。例如下面
    就是一个 jndi.properties的例子:
   
java.naming.factory.object=com.sun.jndi.ldap.AttrsToCorba:com.wiz.from.Person
java.naming.factory.state=com.sun.jndi.ldap.CorbaToAttrs:com.wiz.from.Person
java.naming.factory.control=com.sun.jndi.ldap.ResponseControlFactory
java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
java.naming.provider.url=ldap://localhost:389/o=jnditutorial
com.sun.jndi.ldap.netscape.schemaBugs=true

    首先,应用程序会从classpath 里面载入 jndi.properties,如果没有发现,那么会载入JAVA_HOME/lib/
    jndi.properties。
   
    注意:如果你使用这种方式配置JNDI,那么当找不到装个文件的时候,会抛出异常。
   
    当然,我们初始化内容上下文的用法也需要修改一下:

java 代码
  1. InitialContext ctx = new InitialContext();  

 

    1.1.2、通过系统变量设置JNDI
   
    我们可以使用如下的方式来实现这个功能:
   
    # java -Djava.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory \
      -Djava.naming.provider.url=ldap://localhost:389/o=jnditutorial \
      List

    1.1.3、Applet的方式设置JDNI
   
    看这个例子:

java 代码
  1. name=java.naming.factory.initial   
  2. value=com.sun.jndi.ldap.LdapCtxFactory>   
  3.   
  4. name=java.naming.provider.url   
  5. value=ldap://localhost:389/o=jnditutorial>  

    同时初始内容上下文也需要修改:

java 代码
  1. // Put this applet instance into the environment   
  2. Hashtable env = new Hashtable();   
  3. env.put(Context.APPLET, this);   
  4.   
  5. // Pass the environment to the initial context constructor   
  6. Context ctx = new InitialContext(env);   
  7.   
  8. // List the objects    
  9. NamingEnumeration enum = ctx.list(target);   
  10. while (enum.hasMore()) {   
  11.      out.println(enum.next());   
  12. }   
  13. ctx.close();  

    1.2、内容上下文环境的探讨
   
    我们已经知道可以通过三种方式来设置JDNI的属性。但是,如果我们同时使用了两种方式会
    怎么样呢?看看下面的例子:

java 代码
  1. // Initial environment with various properties   
  2. Hashtable env = new Hashtable();   
  3. env.put(Context.INITIAL_CONTEXT_FACTORY,     
  4.     "com.sun.jndi.fscontext.FSContextFactory");   
  5. env.put(Context.PROVIDER_URL, "file:/");   
  6. env.put(Context.OBJECT_FACTORIES, "foo.bar.ObjFactory");   
  7. env.put("foo""bar");   
  8.   
  9. // Call the constructor   
  10. Context ctx = new InitialContext(env);   
  11.   
  12. // See what environment properties you have   
  13. System.out.println(ctx.getEnvironment());  

 

    我们同时配置一个jndi.properties在classpath里:
   
java.naming.factory.object=com.sun.jndi.ldap.AttrsToCorba:com.wiz.from.Person
java.naming.factory.state=com.sun.jndi.ldap.CorbaToAttrs:com.wiz.from.Person
java.naming.factory.control=com.sun.jndi.ldap.ResponseControlFactory
java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
java.naming.provider.url=ldap://localhost:389/o=jnditutorial
com.sun.jndi.ldap.netscape.schemaBugs=true

    然后看看运行的结果:
   
com.sun.jndi.ldap.netscape.schemaBugs=true
java.naming.factory.object=foo.bar.ObjFactory:com.sun.jndi.ldap.AttrsToCorba:com.wiz.from.Person
java.naming.factory.initial=com.sun.jndi.fscontext.FSContextFactory
foo=bar
java.naming.provider.url=file:/
java.naming.factory.state=com.sun.jndi.ldap.CorbaToAttrs:com.wiz.from.Person
java.naming.factory.control=com.sun.jndi.ldap.ResponseControlFactory

    下面来分析一下这个结果:
   
    a> 在 Hashtable 里的“foo”项,和在文件里的 “com.sun.jndi.ldap.netscape.schemaBugs”,
       都出现在结果里。
    b> “java.naming.factory.object” 项是两者的组合。
    c> 其他的属性如“java.naming.factory.initial” 都是用的 Hashtable里的。
   
    是不是有些混乱?如果我们要使用多个SPI该怎么办?没关系,我们在下一个小结里介绍这个问题。
   
    1.3、定制使用SPI
   
    你可以通过一个SPI的属性文件,来为某一个SPI进行单独的设置。这个文件也是 .properties 文件。
    SPI的属性文件应该类似下面:
   
    前缀/jndiprovider.properties
   
    这个前缀是什么呢?就是这个SPI实现的内容上下文类(Context)的包的结构。
    例如,我们要使用的是 com.sun.jndi.ldap.LdapCtx 这个内容上下文,那么对应于它的属性配置
    文件就应该是:"com/sun/jndi/ldap/jndiprovider.properties"。
    一个应用可以使用多个这样的属性配置文件。
   
    那么我们为什么要使用属性配置文件?
    有两个原因。第一,我们可以单独的配置某一个命名/服务系统。第二,部署的时候会有用。例如,
    你可以单独配置一个针对LDAP的属性,而不用去修改 jndi.properties,或者增加系统变量。
   
    但是,我们也并不是可以在SPI属性配置文件里设置全部的属性,我们可以设置的属性如下:
   
java.naming.factory.object
java.naming.factory.state
java.naming.factory.control
java.naming.factory.url.pkgs

    不过并不象 jndi.properties 或者 那个Hastable,SPI属性配置文件里的属性不会自动载入到环境
    里,只有SPI调用了下列方法时才会这样做:
   
NamingManager.getObjectInstance(Object, Name, Context, Hashtable)
DirectoryManager.getObjectInstance(Object, Name, Context, Hashtable, Attributes)
NamingManager.getStateToBind(Object, Name, Context, Hashtable)
DirectoryManager.getStateToBind(Object, Name, Context, Hashtable, Attributes)
ControlFactory.getControlInstance(Control, Context, Hashtable)

    例如,假设我们使用一个LDAP服务,它的实现类是com.sun.jndi.ldap.LdapCtx,当这个类调用
    DirectoryManager.getObjectInstance() 方法时,JNDI将会从com/sun/jndi/ldap/jndiprovider.properties
    里找到“java.naming.factory.object”项,然后把它追加到环境里已经定义的项里(例如那个Hashtable
    或者 jndi.properties)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值