jndi-ejb
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.
<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.
<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名称):
下面是另外一个例子:
<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>
FooHome fh = (FooHome) PortableRemoteObject.narrow(home, FooHome.class);
同样的,这里也避免了在java代码中显示的调用JNDI名称。
实际上不需要上面的2段也可以得到应用服务器中的资源(只需要得到一个InitalContext,当JNDI服务启动之后就可以通过lookup得到需要的资源了)。
下面是一个利用RMI访问weblogic的例子:
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.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();