weblogic启动后会产生一个RMI Register的service并管理JNDI tree
weblogic.xml: http://download.oracle.com/docs/cd/E13222_01/wls/docs81/webapp/weblogic_xml.html#1054859
The reference-descriptor element maps a name used in the Web application to the JNDI name of a server resource.
<!--
weblogic.xml entry:
-->
<
resource-description
>
<
res-ref-name
>
jdbc/myds
</
res-ref-name
>
<
jndi-name
>
myDataSource
</
jndi-name
>
</
resource-description
>
web.xml: http://download.oracle.com/docs/cd/E13222_01/wls/docs81/webapp/web_xml.html#1045815
The optional resource-ref element defines a reference lookup name to an external resource. This allows the servlet code to look up a resource by a "virtual" name that is mapped to the actual location at deployment time.
<!--
web.xml entry:
-->
<
resource-ref
>
<
res-ref-name
>
jdbc/myds
</
res-ref-name
>
<
res-type
>
javax.sql.DataSource
</
res-type
>
<
res-auth
>
Container
</
res-auth
>
</
resource-ref
>
配置好引用之后我们可以通过如下的方式使用名称jdbc/myds(这样可以避免在java代码中直接调用JNDI名称):
javax.sql.DataSource ds
=
(javax.sql.DataSource) ctx.lookup(
"
java:comp/env/jdbc/myds
"
);
下面是另外一个例子:
<!--
web.xml entry:
-->
<
ejb-ref
>
<
ejb-ref-name
>
ejb/foohome
</
ejb-ref-name
>
<
ejb-ref-type
>
Session
</
ejb-ref-type
>
<
home
>
com.foo.bar.FooHome
</
home
>
<
remote
>
com.foo.bar.Foo
</
remote
>
</
ejb-ref
>
<!--
weblogic.xml entry:
-->
<
ejb-reference-description
>
<
ejb-ref-name
>
ejb/foohome
</
ejb-ref-name
>
<
jndi-name
>
FooHome
</
jndi-name
>
</
ejb-reference-description
>
Object home
=
ctx.lookup(
"
java:comp/env/ejb/foohome
"
);
FooHome fh
=
(FooHome) PortableRemoteObject.narrow(home, FooHome.
class
);
同样的,这里也避免了在java代码中显示的调用JNDI名称。
实际上不需要上面的2段也可以得到应用服务器中的资源(只需要得到一个InitalContext,当JNDI服务启动之后就可以通过lookup得到需要的资源了)。
下面是一个利用RMI访问weblogic的例子:
1
--
get remote object and the usage of RMI(PortableRemoteObject)
2
Properties properties
=
new
Properties();
--
Properties
extends
HashTable
3
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"
weblogic.jndi.WLInitialContextFactory
"
);
4
properties.put(Context.PROVIDER_URL,
"
t3://localhost:7001
"
);
5
InitialContext initialcontext
=
new
InitialContext(properties);
6
Object obj
=
null
;
7
obj
=
initialcontext.lookup(
"
jndiname
"
);
8
TestHome testHome
=
(TestHome)PortableRemoteObject.narrow(obj, com.TestHome.
class
);
9
Test test
=
testHome.create();
10
11
String str
=
test.getDOM(s,s1,s2);
12
Document document
=
XmlUtil.String2DOM(str);
13
......
14
15
-------------------------------------------
16
--
EJBHome:
17
public
interface
TestHome
18
extends
EJBHome
19
{
20
21
public
abstract
Test create()
22
throws
RemoteException, CreateException;
23
}
24
25
--
EJBObject
26
public
interface
Test
27
extends
EJBObject
28
{
29
30
public
abstract
String getDOM(String s, String s1, String s2)
31
throws
RemoteException, Exception;
32
33
public
abstract
Document getDOM(Document document, Document document1, String s)
34
throws
RemoteException, Exception;
35
}
利用jndi获取数据源的一个例子
利用J2EE建立一个Application Client Project如下:
首先启动weblogic,建立一个连接池Test Pool, 然后利用此连接池创建一个DataSource:TEST_DS
import
java.lang.reflect.Method;
import
java.sql.Connection;
import
java.sql.ResultSet;
import
java.sql.Statement;
import
java.util.Hashtable;
import
javax.naming.Context;
import
javax.naming.InitialContext;
import
javax.rmi.PortableRemoteObject;
import
javax.sql.DataSource;
public
class
Main {
public
static
void
main(String[] args)
throws
Exception{
Context ctx
=
null
;
Hashtable env
=
new
Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"
weblogic.jndi.WLInitialContextFactory
"
);
env.put(Context.PROVIDER_URL,
"
t3://localhost:7001
"
);
ctx
=
new
InitialContext(env);
Object obj
=
ctx.lookup(
"TEST
_DS
"
);
//
通过PortableObject获取conn对象,效率比较高
DataSource ds
=
(DataSource) PortableRemoteObject.narrow(obj, DataSource.
class
);
Connection conn
=
ds.getConnection();
/*
利用反射也可以获取到conn,但是效率没有上面的快
Class class1 = obj.getClass();
Class paramType[] = new Class[0];
Object param[] = new Object[0];
Method method = class1.getMethod("getConnection", paramType);
Connection conn = (Connection)method.invoke(obj, param);
*/
Statement stmt
=
conn.createStatement();
String sql
=
"
select sysdate from dual
"
;
ResultSet rs
=
stmt.executeQuery(sql);
while
(rs.next()) {
System.out.println(rs.getDate(
1
));
}
}
public
Main() {
super
();
}
}
Tomcat下JNDI:
第一步:
打开tomcat目录下的conf/service.xml文件。在<Host></Host>中加入数据源配置信息:
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="/Test" docBase="Test" debug="0" privileged="true" reloadable="true" crossContext="true">
<Resource name="jdbc/mssql" type="javax.sql.DataSource"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" password="123456" maxIdle="2" maxWait="5000" username="tang"
url="jdbc:sqlserver://192.168.1.3:1433;DatabaseName=mydb" maxActive="1000"/>
</Context>
</Host>
第二步:
打开项目中的web.xml文件添加:
<resource-ref>
<res-ref-name>jdbc/mssql</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
第三步:
启动Tomcat,在项目中添加测试代码:
public static void initDataSource() {
String dsn = "java:comp/env/jdbc/mssql";
System.out.println("Attempting to connect to " + dsn);
try ...{
System.out.println("Initializing the naming context...");
InitialContext init = new InitialContext();
System.out.println("Looking up " + dsn);
datasource = (DataSource) init.lookup(dsn);
Connection con = datasource.getConnection();
System.out.println("DataSource initialze successfully!");
} catch (Exception e) ...{
logger.error(e);
e.printStackTrace();