JNDI + Spring 如何读取数据
首先来谈谈什么是JNDI:
JNDI官方给出的定义是:Java Naming and Directory Interface,Java命名和目录接口.
而JNDI实际的作用就是将一些资源信息与java对象关联起来。
在JAVA开发中 使用到最多的场景则是与数据源的配置。当然数据源信息可以以固定的参数形式写在xml中,然后通过dataSource进行数据库的连接。
而JNDI的加入可以将数据源的信息与java项目解耦,通过在J2EE容器中配置JNDI参数,定义一个数据源,并给这个数据源命名。
然后在程序里直接引用这个JNDI的名称,既可通过名称访问对应JNDI所定义的数据源。这样做的优点就是实现数据源信息与程序解耦
如果当数据源发生变更则可以直接修改容器中数据源的资料即可,只要程序中数据源的名称与JNDI的名称保持不变,那么程序就无需做任何改变。
这几天一直在研究JNDI 是如何读取数据的。发现针对不同的服务器(tomcat,weblogic.....)JNDI的初始化配置是不同的。
先看看正常java代码的实现过程:
tomcat
首先要在tomcat conf/context文件中配置好数据。例如
<Resource name="jdbc/test" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1/test" username="root" password="root" maxActive="20" maxIdle="10" maxWait="-1"/>
数据库的参数就不一一介绍了
name:表示JNDI可以通过这个name属性找到这段数据
auth:表示由容器进行授权管理,使得数据库的帐号密码可以在容器上生效(对于其他不需要用户密码的数据就不需要 该属性了)
Type:现在是定义dataSource这个类的全路径,也可以是自己定义的类,如果是自己定义的类 想让JNDI识别出来的话需要加上
factory="org.apache.naming.factory.BeanFactory"
这个beanFactory也是Spring管理bean的根接口,所以当使用到自定义的类的时候需要加上这个属性。不然JNDI无法识别你自定义的类
java代码
InitialContext initCtx = new InitialContext();
DataSource data = (DataSource) initCtx.lookup("java:comp/env/jdbc/test");
单纯的使用main方法执行上面的代码是无效的,因为我们的参数是存放在tomcat的容器内,所以需要将上面的代码与项目同时启动,才能读取到数据。
这个时候data对象内的参数就是resource中定义的参数内容了!!
weblogic
weblogic的数据可以以properties文件的形式放在weblogic目录中
Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); env.put(Context.PROVIDER_URL, "t3://localhost:7000"); InitialContext initCtx = new InitialContext(env); Object data = (DataSource) initCtx.lookup("resouce");
initialContext只支持hashTable,所以我们将参数封装好,再初始化JNDI。上面说到每个服务器对JNDI的支持都大同小异,而weblogic.jndi.WLInitialContextFactory 就是weblogic对JNDI的初始化接口。
针对不同的服务器他们接口的路径也不同,例如JBoss则是org.jnp.interfaces.NamingContextFactory这个路径,所以这个Factory参数要以具体情况定义,tomcat是不需要的哟!!URL就是
服务器weblogic的地址。而T3也是一种协议,只是他是weblogic特有的。lookup的参数也有所不同,weblogic对应的是properties文件的名字即可 也可以是一整个文件路径,而根目录就是weblogic,然后往下查找
(weblogic.jms.jade.Ord_TPC)类似这样,用点号来做文件夹的区分。 上诉tomcat中用的是java:comp/env这样的形式,这个是web特有的。即java:comp/env/xxx/xxx代表的就是context中配置的数据了。
使用spring配置来加载数据
<!--jndi环境配制 --> <bean id="jndiTopicTemplate" class="org.springframework.jndi.JndiTemplate"> <property name="environment"> <props> <prop key="java.naming.factory.initial"> weblogic.jndi.WLInitialContextFactory </prop> <prop key="java.naming.provider.url"> ${jms.broker.url} </prop> </props> </property> </bean> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="${topic.factory.name}" /> <property name="jndiTemplate" ref="jndiTopicTemplate" /> </bean>
这个时候dataSource就是一个带有连接配置参数的对象,可以在spirng中直接引用即可。
上面介绍了这么多用法,JNDI适用的场景我觉得还是,有些配置(比如数据库这样正式的连接地址不宜暴露的时候)可以使用这样的方式来配置,让使用这个连接的人只能使用,却
没法具体知道具体的数据是怎么样的。对于大企业的保密工作应该是个不错的支持吧!!!