JNDI(Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象。目录服务是一种命名服务,在这种服务里,对象不但有名称,还有属性。 (http://baike.baidu.com/view/209575.htm)
JNDI服务是WEB容器提供的服务。WEB应用可以通过JNDI服务从容器中得到各种组件(包括但不限于数据源),实现各组件的解耦。
以下举一个例子。
在tomcat的conf/server.xml中配置:
- <Context path="/jndi">
- <Resource name="bean/MyBeanFactory" auth="Container"
- type="com.huawei.jndi.bean.MyBean"
- factory="org.apache.naming.factory.BeanFactory"
- bar="23"/>
- </Context>
<Context path="/jndi"> <Resource name="bean/MyBeanFactory" auth="Container" type="com.huawei.jndi.bean.MyBean" factory="org.apache.naming.factory.BeanFactory" bar="23"/> </Context>
上面就在tomcat中声明了一个组件,接下来在代码中可以获取这个组件:
- try
- {
- Context initContext = new InitialContext();
- Context envCtx = (Context) initContext.lookup("java:comp/env");
- MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");
- System.out.println(bean.getBar());
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
try
{
Context initContext = new InitialContext();
Context envCtx = (Context) initContext.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");
System.out.println(bean.getBar());
}
catch (Exception e)
{
e.printStackTrace();
}
总结:在tomcat中配置jndi组件,然后在代码中获取已配好的组件。
各WEB容器的JNDI实现类是不同的,比如在JBOSS中,JNDI提供类是org.jnp.interfaces.NamingContextFactory,与tomcat是不同的。
这样看来,JNDI的作用和spring的依赖注入倒是差不多。但是 通过JNDI,可以实现跨应用,甚至跨域获取组件。在服务器A上配置的组件,在另一台服务器B上,可以通过JNDI获取到。
spring也提供了对jndi的封装,使用起来更加方便,以下是一个例子。
- <!-- JNDI模板 -->
- <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
- <property name="environment">
- <props>
- <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
- <prop key="java.naming.provider.url">10.137.96.212:18199</prop>
- <prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop>
- </props>
- </property>
- </bean>
- <!-- 创建连接工厂 -->
- <bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
- <property name="jndiTemplate" ref="jndiTemplate" />
- <property name="jndiName" value="TopicConnectionFactory" />
- </bean>
<!-- JNDI模板 --> <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> <property name="environment"> <props> <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop> <prop key="java.naming.provider.url">10.137.96.212:18199</prop> <prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop> </props> </property> </bean> <!-- 创建连接工厂 --> <bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiTemplate" ref="jndiTemplate" /> <property name="jndiName" value="TopicConnectionFactory" /> </bean>
先声明JndiTemplate,配置好目标地址、JNDI服务提供类。然后通过JndiObjectFactoryBean,就可以很方便地获取JNDI组件,并进行类型转换。