打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Java技术回顾之JNDI(一):JNDI应用实例,Java技术文章,Java系列教程,Java

一、JNDI在Java EE中的应用
JNDI技术是Java EE规范中的一个重要“幕后”角色,它为Java EE容器、组件提供者和应用程序之间提供了桥梁作用:JavaEE容器同时扮演JNDI提供者角色,组件提供者将某个服务的具体实现部署到容器上,应用程序通过标准的JNDI接口就可以从容器上发现并使用服务,而不用关心服务的具体实现是什么,它的具体位置在哪里。

下面以一个常见的J2EE应用场景来看四种角色(组件接口、容器、组件提供者、应用程序)是如何围绕JNDI来发挥作用的:
组件接口
数据源DataSource是一种很常见的服务。我们通常将组件接口绑定到容器的Context上供客户调用。

Java EE容器
Tomcat是一种常见的JavaEE容器,其他的还有JBoss,WebLogic,它们同时也实现了JNDI提供者规范。容器通常提供一个JNDI注入场所供加入组件的具体实现,比如Tomcat中的Server.xml配置文件。

组件提供者
众多数据库厂商提供了DataSource的实现,比如OracleDataSource,MySQLDataSource,XXXDataSource等。我们将该实现的部署到容器中:将一系列jar加入classpath中,在Server.xml中配置DataSource实现,如:
<Resourcename="jdbc/MyDB" auth="Container" type="javax.sql.DataSource" ..../>

应用程序
一个JSP/Servlet应用程序。通过JNDI接口使用DataSource服务,如:
Context initContext = new InitialContext();
ContextenvContext  = (Context)initContext.lookup("java:/comp/env");
DataSourceds = (DataSource)envContext.lookup("jdbc/MyDB");

关于在Tomcat中如何配置DataSource,可以参考文档:http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html
关于在Tomcat中如何配置其他JNDI服务,可以参考文档:
http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html

二、JNDI实例演练:在Java SE中使用JNDI
要在JavaEE中环境中提供一个独立的实例不太容易。下面以一个独立的JavaSE应用来演练JNDI的使用过程。在该应用中,我们使用JNDI来使用两种假想的服务:数据库服务DBService和日志服务LogService。

1、指定JNDI提供者
要使用JNDI,首先要配置JNDI提供者。在我们的Java SE应用中,没有JavaEE容器充当JNDI提供者,因此我们要指定其他的JNDI提供者。在我们的例子里,我们使用SUN的文件系统服务提供者File SystemService Provider。由于SUN的文件系统服务提供者并没有包含在JDK中,我们需要从SUN网站上下载:
http://java.sun.com/products/jndi/downloads/index.html。它包含两个jar文件:fscontext.jar和providerutil.jar。我们将这两个文件加入项目的类路径中。

2、定义服务接口
首先,我们在服务接口package(xyz.service)中定义服务接口:DBService和LogService,分别表示数据库服务和日志服务。

♦数据库服务接口 DBService.java

package xyz.service;

public interface DBService {
 StringgetLocation(); //获取数据库位置

 String getState(); //获取数据库状态
 
 voidaccessDB(); //访问数据库
 
 void setProperty(int index,Stringproperty); //设置数据库信息
}


♦日志服务接口 LogService.java

package xyz.service;

public interface LogService {
 voidlog(String message); //记录日志
}

3、组件提供者实现服务接口
接下来,我们在组件提供者package(xyz.serviceprovider)中提供DBService和LogService的实现:SimpleDBService和SimpleLogService。为了让服务能够在JNDI环境中使用,根据JNDI规范,我们同时定义两个对象工厂类SimpleDBServiceFactory和SimpleLogServiceFactory,分别用来创建服务实例。

♦数据库服务接口实现  SimpleDBService.java


package xyz.serviceprovider;

importjavax.naming.NamingException;
import javax.naming.Reference;
importjavax.naming.Referenceable;
import javax.naming.StringRefAddr;

import xyz.service.DBService;

//为了将数据库服务实例加入JNDI的Context中,我们需要实现Referenceable接口,并实现RetReference方法。
//关于Reference和Referenceable,请参考上一篇:Java技术回顾之JNDI:JNDI API
public class SimpleDBService implementsReferenceable, DBService {
 private Stringlocation="mydb//local:8421/defaultdb";//数据库服务属性之一:数据库位置
 privateString state="start"; //数据库服务属性之二:数据库状态

 public Reference getReference()throws NamingException {
  //Reference是对象的引用,Context中存放的是Reference,为了从Reference中还原出对象实例,
  //我们需要添加RefAddr,它们是创建对象实例的线索。在我们的SimpleDBService中,location和state是这样两个线索。
  Reference ref=newReference(getClass().getName(),SimpleDBServiceFactory.class.getName(),null);
  ref.add(newStringRefAddr("location",location));
  ref.add(newStringRefAddr("state",state));
  return ref;
 }

 public void accessDB() {
  if(state.equals("start"))
   System.out.println("weare accessing DB.");
  else
   System.out.println("DB is notstart.");
 }

 public String getLocation() {
  returnlocation;
 }

 public String getState() {
  return state;
 }

 public void setProperty(intindex,String property){
  if(index==0)
   location=property;
  else
   state=property;
 }
}

♦数据库服务对象工厂类 SimpleDBServiceFactory.java

package xyz.serviceprovider;

import java.util.Hashtable;

import javax.naming.Context;
importjavax.naming.Name;
import javax.naming.Reference;
importjavax.naming.spi.ObjectFactory;

//数据库服务对象工厂类被JNDI提供者调用来创建数据库服务实例,对使用JNDI的客户不可见。
public class SimpleDBServiceFactory implementsObjectFactory {

 //根据Reference中存储的信息创建出SimpleDBService实例
 publicObject getObjectInstance(Object obj, Name name, Context ctx,
   Hashtable<?,?> env) throws Exception {
  if(obj instanceof Reference){
   Referenceref=(Reference)obj;
   Stringlocation=(String)ref.get("location").getContent();
   Stringstate=(String)ref.get("state").getContent();
   SimpleDBService db=new SimpleDBService();
   db.setProperty(0, location);
   db.setProperty(1,state);
   return db;
  }
  return null;
 }
}


♦日志服务接口实现 SimpleLogService.java

packagexyz.serviceprovider;

import java.text.SimpleDateFormat;
importjava.util.Date;

import javax.naming.NamingException;
importjavax.naming.Reference;
import javax.naming.Referenceable;

import xyz.service.LogService;

public class SimpleLogServiceimplements Referenceable, LogService {
 private SimpleDateFormatsdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

 //SimpleLogService没有任何属性,通过SimpleLogService类名创建出来的SimpleLogService实例都是一样的,
 //因此这里无需添加RefAddr了。
 publicReference getReference() throws NamingException {
  return newReference(getClass().get
Name(),SimpleLogServiceFactory.class.getName(),null);
 }

 public void log(Stringmessage) {
  String date=sdf.format(new Date());
  System.out.println(date+":"+message);
 }
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
警告!与Log4Shell相似的Java漏洞出现了
在 Java 客户端中使用 SSL 身份验证
TOMCAT的安全域(Realm)
tomcat6.0配置jndi在spring中使用
Java中的事务
WebLogic使用总结(三)——WebLogic配置JNDI数据源
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服