<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    瘋狂

    STANDING ON THE SHOULDERS OF GIANTS
    posts - 481, comments - 486, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    JNDI(轉載)

    Posted on 2010-01-19 13:13 瘋狂 閱讀(1341) 評論(0)  編輯  收藏 所屬分類: java
    文章來自:http://www.java3z.com/cwbwebhome/article/article2/21040.html?id=1780

      一、JNDI在Java EE中的應用
       JNDI技術是Java EE規范中的一個重要“幕后”角色,它為Java EE容器、組件提供者和應用程序之間提供了橋梁作用:Java EE容器同時扮演JNDI提供者角色,組件提供者將某個服務的具體實現部署到容器上,應用程序通過標準的JNDI接口就可以從容器上發現并使用服務,而不用關心服務的具體實現是什么,它的具體位置在哪里。

        下面以一個常見的J2EE應用場景來看四種角色(組件接口、容器、組件提供者、應用程序)是如何圍繞JNDI來發揮作用的:
    組件接口
        數據源DataSource是一種很常見的服務。我們通常將組件接口綁定到容器的Context上供客戶調用。

    Java EE容器
        Tomcat是一種常見的Java EE容器,其他的還有JBoss,WebLogic,它們同時也實現了JNDI提供者規范。容器通常提供一個JNDI注入場所供加入組件的具體實現,比如Tomcat中的Server.xml配置文件。

    ? 組件提供者
           眾多數據庫廠商提供了DataSource的實現,比如OracleDataSource,MySQLDataSource,XXXDataSource等。我們將該實現的部署到容器中:將一系列jar加入classpath中,在Server.xml中配置DataSource實現,如:
    <Resource name="jdbc/MyDB" auth="Container" type="javax.sql.DataSource" ..../>

    應用程序
    一個JSP/Servlet應用程序。通過JNDI接口使用DataSource服務,如:
    Context initContext = new InitialContext();
    Context envContext  = (Context)initContext.lookup("java:/comp/env");
    DataSource ds = (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
       要在Java EE中環境中提供一個獨立的實例不太容易。下面以一個獨立的Java SE應用來演練JNDI的使用過程。在該應用中,我們使用JNDI來使用兩種假想的服務:數據庫服務DBService和日志服務LogService。

    1、指定JNDI提供者
    要使用JNDI,首先要配置JNDI提供者。在我們的Java SE應用中,沒有Java EE容器充當JNDI提供者,因此我們要指定其他的JNDI提供者。在我們的例子里,我們使用SUN的文件系統服務提供者File System Service 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 {
     String getLocation(); //獲取數據庫位置

     String getState(); //獲取數據庫狀態
     
     void accessDB(); //訪問數據庫
     
     void setProperty(int index,String property); //設置數據庫信息
    }


    日志服務接口 LogService.java

    package xyz.service;

    public interface LogService {
     void log(String message); //記錄日志
    }

    3、組件提供者實現服務接口
      接下來,我們在組件提供者package(xyz.serviceprovider)中提供DBService和LogService的實現:SimpleDBService和SimpleLogService。為了讓服務能夠在JNDI環境中使用,根據JNDI規范,我們同時定義兩個對象工廠類SimpleDBServiceFactory和SimpleLogServiceFactory,分別用來創建服務實例。

    數據庫服務接口實現  SimpleDBService.java


    package xyz.serviceprovider;

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

    import xyz.service.DBService;

    //為了將數據庫服務實例加入JNDI的Context中,我們需要實現Referenceable接口,并實現RetReference方法。
    //關于Reference和Referenceable,請參考上一篇:Java技術回顧之JNDI:JNDI API
    public class SimpleDBService implements Referenceable, DBService {
     private String location="mydb//local:8421/defaultdb";//數據庫服務屬性之一:數據庫位置
     private String state="start"; //數據庫服務屬性之二:數據庫狀態

     public Reference getReference() throws NamingException {
      //Reference是對象的引用,Context中存放的是Reference,為了從Reference中還原出對象實例,
      //我們需要添加RefAddr,它們是創建對象實例的線索。在我們的SimpleDBService中,location和state是這樣兩個線索。
      Reference ref=new Reference(getClass().getName(),SimpleDBServiceFactory.class.getName(),null);
      ref.add(new StringRefAddr("location",location));
      ref.add(new StringRefAddr("state",state));
      return ref;
     }

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

     public String getLocation() {
      return location;
     }

     public String getState() {
      return state;
     }

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

    數據庫服務對象工廠類 SimpleDBServiceFactory.java

    package xyz.serviceprovider;

    import java.util.Hashtable;

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

    //數據庫服務對象工廠類被JNDI提供者調用來創建數據庫服務實例,對使用JNDI的客戶不可見。
    public class SimpleDBServiceFactory implements ObjectFactory {

     //根據Reference中存儲的信息創建出SimpleDBService實例
     public Object getObjectInstance(Object obj, Name name, Context ctx,
       Hashtable<?, ?> env) throws Exception {
      if(obj instanceof Reference){
       Reference ref=(Reference)obj;
       String location=(String)ref.get("location").getContent();
       String state=(String)ref.get("state").getContent();
       SimpleDBService db= new SimpleDBService();
       db.setProperty(0, location);
       db.setProperty(1, state);
       return db;
      }
      return null;
     }
    }


    日志服務接口實現 SimpleLogService.java


    package xyz.serviceprovider;

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

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

    import xyz.service.LogService;

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

     //SimpleLogService沒有任何屬性,通過SimpleLogService類名創建出來的SimpleLogService實例都是一樣的,
     //因此這里無需添加RefAddr了。
     public Reference getReference() throws NamingException {
      return new Reference(getClass().getName(),SimpleLogServiceFactory.class.getName(),null);
     }

     public void log(String message) {
      String date=sdf.format(new Date());
      System.out.println(date+":"+message);
     }
    }

    日志服務對象工廠類 SimpleLogServiceFactory.java

    p
    ackage xyz.serviceprovider;

    import java.util.Hashtable;

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

    public class SimpleLogServiceFactory implements ObjectFactory {

     public Object getObjectInstance(Object obj, Name name, Context ctx,
       Hashtable<?, ?> env) throws Exception {
      if(obj instanceof Reference){
       return new SimpleLogService();
      }
      return null;
     }
    }

     4、JNDI容器和JNDI客戶端
        最后,我們在JNDI應用package(xyz.jndi)中實現一個JNDI容器JNDIContainer和一個JNDI客戶端應用JNDIClient。
    JNDIContainer在內部使用文件系統服務提供者fscontext來提供命名和目錄服務,配置文件JNDIContainer.properties是服務注入場所,供配置DBService和LogService實現。

    JNDI容器類 JNDIContainer.java

    package xyz.jndi;

    import java.io.InputStream;
    import java.util.Hashtable;
    import java.util.Properties;

    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;

    import xyz.service.DBService;
    import xyz.service.LogService;

    public class JNDIContainer {

     private Context ctx=null;
     
     public void init() throws Exception{
         //初始化JNDI提供者。
         Hashtable env = new Hashtable();
         env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
         env.put(Context.PROVIDER_URL, "file:/c:/sample"); //fscontext的初始目錄,我們需要在c:\下創建sample目錄。
         ctx=new InitialContext(env);
         loadServices();
     }
     
     //從配置文件JNDIContainer.properties中讀取DBService和LogService實現,綁定到Context中。
     private void loadServices() throws Exception{
      InputStream in=getClass().getResourceAsStream("JNDIContainer.properties");
      Properties props=new Properties();
      props.load(in);
      
      //inject dbservice
      String s=props.getProperty("DBServiceClass");
      Object obj=Class.forName(s).newInstance();
      if(obj instanceof DBService){
       DBService db=(DBService)obj;
       String[] ss=props.getProperty("DBServiceProperty").split(";");
       for(int i=0;i<ss.length;i++)
        db.setProperty(i, ss[i]);
       ctx.rebind(props.getProperty("DBServiceName"), db);
      }
      
      //inject logservice
      s=props.getProperty("LogServiceClass");
      obj=Class.forName(s).newInstance();
      if(obj instanceof LogService){
       LogService log=(LogService)obj;
       ctx.rebind(props.getProperty("LogServiceName"), log);
      }
     }
     
     public void close() throws NamingException{
      ctx.close();
     }
     
     public Context getContext(){
      return ctx;
     }
    }

    JNDI容器配置文件 JNDIContainer.properties

    //和JNDIContainer.java文件位于同一目錄
    DBServiceName=DBService
    DBServiceClass=xyz.serviceprovider.SimpleDBService
    DBServiceProperty=mydb//192.168.1.2:8421/testdb;start

    LogServiceName=LogService
    LogServiceClass=xyz.serviceprovider.SimpleLogService

    JNDI客戶端 JNDIClient.java

    package xyz.jndi;

    import javax.naming.Context;

    import xyz.service.DBService;
    import xyz.service.LogService;

    public class JNDIClient {
     
     public static void main(String[] args){
      try{
       JNDIContainer container=new JNDIContainer();
       container.init();
       
          //JNDI客戶端使用標準JNDI接口訪問命名服務。
          Context ctx=container.getContext();
          DBService db=(DBService)ctx.lookup("DBService");
          System.out.println("db location is:"+db.getLocation()+",state is:"+db.getState());
          db.accessDB();
         
          LogService ls=(LogService)ctx.lookup("LogService");
          ls.log("this is a log message.");
         
          container.close();
      }
      catch(Exception e){
       e.printStackTrace();
      }
     }
    }

    至此,我們的整個Java SE應用已經完成。

    主站蜘蛛池模板: h片在线观看免费| 亚洲AV无码国产一区二区三区| 天堂亚洲免费视频| 亚洲日韩国产二区无码| 又粗又大又黑又长的免费视频| 夫妻免费无码V看片| 亚洲一区在线免费观看| 久久精品国产亚洲AV| 免费理论片51人人看电影| 亚洲综合小说另类图片动图 | 在线免费观看a级片| 亚洲第一区二区快射影院| 中文字幕免费人成乱码中国| 成人免费视频77777| 亚洲天堂2016| 国产美女无遮挡免费视频网站 | 国产精品亚洲综合五月天| 野花高清在线电影观看免费视频 | 国产成人亚洲精品| 日韩精品免费一区二区三区| 男人j进女人p免费视频| 日本亚洲免费无线码| 国产精品高清视亚洲一区二区 | 久久久久亚洲精品成人网小说| 18禁在线无遮挡免费观看网站| 亚洲一区二区三区电影| 国产免费不卡v片在线观看| 亚洲a∨国产av综合av下载 | 亚洲午夜久久影院| 欧洲精品成人免费视频在线观看| 亚洲成a∧人片在线观看无码 | 成人片黄网站色大片免费观看APP| 亚洲A∨无码无在线观看| 永久免费的网站在线观看| 另类图片亚洲校园小说区| 国产亚洲精久久久久久无码| 午夜国产精品免费观看| 窝窝影视午夜看片免费| 亚洲精品无码av天堂| 国产精品亚洲色图| 亚洲AV无码一区二区三区系列|