对java:comp/env的研究
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
這兩天研究了一下 context.lookup("java:comp/env/XXX")和直接context.lookup("XXX")的區(qū)別?
網(wǎng)上關(guān)于這兩個(gè)的文章也很多,但是都說得很難理解,比如什么ENC環(huán)境啊什么的,各種概念。?
其實(shí)說得簡單點(diǎn):context.lookup("java:comp/env/XXX")只能用在J2EE環(huán)境,即是如果你自己寫一個(gè)main函數(shù),想通過context.lookup("java:comp/env/XXX")這樣的方式來訪問JNDI服務(wù),這是不可能的。?
因?yàn)?#xff1a;java:comp/env/是一個(gè)J2EE環(huán)境的定義,說白了就是代表當(dāng)前J2EE應(yīng)用的環(huán)境,比如你自己項(xiàng)目的Web環(huán)境或者是EJB環(huán)境,那是不是只要是個(gè)Web項(xiàng)目,就能用context.lookup("java:comp/env/XXX")這種方式訪問JNDI服務(wù)了呢?也不是!!!?
使用這樣的方式必須做一次 當(dāng)前應(yīng)用環(huán)境 到 資源名 的映射。?
在web.xml文件中有這樣的標(biāo)簽:?
<resource-env-ref></resource-env-ref>?
<resource-ref></resource-ref>?
<ejb-local-ref></ejb-local-ref>??
<ejb-ref></ejb-ref>?
這些標(biāo)簽就是用來建立當(dāng)前應(yīng)用環(huán)境到服務(wù)器資源的映射的。?
有了這樣的映射之后,就能采用context.lookup("java:comp/env/XXX")的方式來訪問JNDI資源了。?
注意:context.lookup("XXX")在任何時(shí)候都是有效的,只要XXX確實(shí)是一個(gè)存在的JNDI名。?
舉個(gè)例子:?
用weblogic10的控制臺(tái)定了了一個(gè)oracle數(shù)據(jù)源,這個(gè)數(shù)據(jù)源的JNDI名稱是:adsl,那么只要正確連接上了weblogic(當(dāng)然需傳遞URL,用戶名和密碼還有weblogic的JNDI工廠對(duì)象,這不屬于該文的討論范圍)在任何地方都能用context.lookup("xxx")得到這個(gè)數(shù)據(jù)源了,但是想通過context.lookup("java:comp/env/jdbc/adsl")訪問到這個(gè)數(shù)據(jù)源,就不行了。如果想這樣寫的話需要做兩件事情:?
1、確保你的調(diào)用程序是一個(gè)web項(xiàng)目或者EJB項(xiàng)目,并部署到weblogic上。(例子使用web項(xiàng)目)?
2、在web項(xiàng)目的web.xml里面加上如下配置:?
<resource-ref>?
? <res-ref-name>jdbc/adsl</res-ref-name>?
? <res-auth>Container</res-auth>?
? <mapped-name>adsl</mapped-name> <!-- 這個(gè)必須和你的全局JNDI數(shù)據(jù)源名稱一樣 -->??
</resource-ref>?
那么你就能在你的web程序里通過context.lookup("java:comp/env/jdbc/adsl")訪問到這個(gè)數(shù)據(jù)源了。?
關(guān)于EJB的訪問也類似這樣,可以直接訪問全局EJB的JNDI名,和可以映射之后從java:comp/env/下進(jìn)行訪問。?
以上的講解有錯(cuò)。。。。。?
上面的情況只適用于weblogic和J2EE 2.5的規(guī)范下。?
一:如果不是J2EE 2.5的規(guī)范:那么在你的web項(xiàng)目的web.xml內(nèi)將根本不會(huì)存在<mapped-name>這個(gè)標(biāo)簽,那么怎樣才能映射全局JNDI資源到你的項(xiàng)目呢??
以weblogic為例,你需要在和web.xml同級(jí)的目錄下建立:weblogic.xml文件,在該文件里面寫上:?
<weblogic-web-app>?
<resource-description>?
<res-ref-name>jdbc/adsl</res-ref-name>?
<jndi-name>adsl</jndi-name><!-- 這個(gè)就是全局JNDI資源名 -->?
</resource-description>?
</weblogic-web-app>?
然后你仍然需要在web.xml里面配置上:?
<resource-ref>?
? <res-ref-name>jdbc/adsl</res-ref-name>?
? <res-auth>Container</res-auth>?
? </resource-ref>?
這樣你才可以在你的程序里面通過context.lookup("java:comp/env/jdbc/adsl")訪問到這個(gè)數(shù)據(jù)源。?
這個(gè)是weblogic.xml的官方幫助文檔:http://edocs.weblogicfans.net/wls/docs92/webapp/weblogic_xml.html?
二:如果不是使用weblogic,可參見這篇文章:http://blog.csdn.net/lovingprince/article/details/6577920?
其實(shí)各種不同的J2EE容器,都用不同的配置方式,以我目前的測試來看,weblogic似乎不能配置“私有的JNDI資源”,就是不能配置自己項(xiàng)目單獨(dú)的JNDI資源(這只是我的觀點(diǎn),我目前沒發(fā)現(xiàn)怎么在weblogic里面配置私有JNDI資源)?
但是研究tomcat6之后發(fā)現(xiàn),tomcat可以配置 全局JNDI 和私有JNDI(注意這里說的Tomcat6):?
!!!首先想要說明的是Tomcat的配置不需要修改web.xml里面的任何內(nèi)容!!!!!?
!!!Tomcat的全局JNDI資源不能直接訪問,必須有java:comp/env/前綴!!!!!!?
??? 全局的JNDI配置在server.xml里面的<GlobalNamingResources>標(biāo)簽里面添加如下配置:?
??? <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"/>?
??? 然后某一個(gè)項(xiàng)目想要引用這個(gè)全局的JNDI,就需要在項(xiàng)目的META-INF下面建立context.xml文件,在里面寫上:?
<?xml version="1.0" encoding="UTF-8"?>?
<Context>?
??? <ResourceLink name="jdbc/test" global="jdbc/test" type="javax.sql.DataSource"/>?
</Context>?
這樣就可以在程序里面通過context.lookup("java:comp/env/jdbc/test")進(jìn)行訪問了。?
??? 私有的JNDI有三種方式可以配置:?
????? 1、可以直接在server.xml里面的<Host>節(jié)點(diǎn)下添加如下配置:?
<Context path="/test_tomcat6_jndi">?
<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"/>?
</Context>?
這樣就可以直接在程序中通過context.lookup("java:comp/env/jdbc/test")訪問了,需要注意的是path="/test_tomcat6_jndi",這個(gè)名字必須和你的項(xiàng)目名稱相同,而且不能少了那個(gè)斜杠,而且你的項(xiàng)目是通過拷貝文件夾到webapps下面的方式進(jìn)行的部署。?
???? 2、 也可以在conf/context.xml里面增加如下配置:?
???? <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"/>?
這樣就可以直接在程序中通過context.lookup("java:comp/env/jdbc/test")訪問了?
????? 3、還可以在項(xiàng)目的WebRoot下面的META-INF文件夾下面創(chuàng)建context.xml文件,再在context.xml文件里面寫上?
<?xml version="1.0" encoding="UTF-8"?>?
<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"/>?
</Context>?
這樣就可以直接在程序中通過context.lookup("java:comp/env/jdbc/test")訪問了?
你可以發(fā)現(xiàn)的是:以上的Tomcat6中的配置不管是全局還是局部,都沒有修改項(xiàng)目的web.xml文件,但是仍然建議在web.xml中進(jìn)行引用,主要是為了項(xiàng)目的遷移,因?yàn)橛械姆?wù)器需要在web.xml中進(jìn)行聲明!?
總之:各種服務(wù)器有時(shí)候確實(shí)有比較大的出入,特別是感覺J2EE中類似<resource-ref>這樣的一些標(biāo)簽仍然不是很理解。
轉(zhuǎn)載于:https://my.oschina.net/ldm95/blog/718242
總結(jié)
以上是生活随笔為你收集整理的对java:comp/env的研究的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#数组解决约瑟夫环问题
- 下一篇: 如何在Mac上安装win10正版系统