java JNDI配置与自定义

本文介绍了Java JNDI的局部配置,以JDBC数据源为例,详细阐述了如何在webapp的META-INF/context.xml中配置,并通过代码展示如何获取数据源。同时,探讨了如何通过JNDI实现自定义对象的实例化,利用ObjectFactory接口创建工厂类,容器会根据配置属性回调工厂类的createObject方法。最后补充了JNDI的本质,即通过factory类将配置属性赋值给目标对象,与Spring的IOC有相似之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一次接触JNDI,废了好长的时间,遇到了好多莫名奇妙的问题,但是终于配置成功。

下面讲解的JNDI都是局部配置,不是全局的。

从最简单的和网上最长见的JDBC数据源讲起。

配置META-INF/context.xml(在webapp下和WEB-INF文件夹并列),初始内容可以从tomcat配置文件的cof/context.xml文件中复制,然后添加内容

<Resource name="jndi/mybatis" 
				auth="Container" 
				type="javax.sql.DataSource" 
				driverClassName="com.mysql.jdbc.Driver" 
				url="jdbc:mysql://localhost:3306/自己的数据库" 
				username="自己的数据库用户名" 
				password="自己的密码" 
				maxActive="20" 
				maxIdle="10" 
				maxWait="10000"/>

然后配置web.xml文件

添加下面的配置

<resource-ref>
  	<description>JNDI DataSource</description>
  	<res-ref-name>jndi/mybatis</res-ref-name>
  	<res-type>javax.sql.DataSource</res-type>
 	<res-auth>Container</res-auth>
  </resource-ref>

注意

res-ref-name必须和上面的name相同

然后可以通过下面的代码获取数据源

context = new InitialContext();

DataSource ds = (DataSource) context.lookup("java:comp/env/jndi/mybatis")


进一步,我们是否可以实现通过jndi获取自定义的对象呢?答案是肯定的,但是不是将类实现成bean实现的,而是通过factory类进行实例化

第一步,自定义类和其factory类(实现ObjectFactory接口的类),我将这两者实现在了一个类中。


/**
 * Alipay.com Inc.
 * Copyright (c) 2004-2014 All Rights Reserved.
 */
package org.footoo.jspTest1;

import java.util.Enumeration;
import java.util.Hashtable;

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

/**
 * 
 * @author jeff
 * @version $Id: UserInfo.java, v 0.1 2014年4月19日 下午1:11:27 jeff Exp $
 */
public class UserInfo implements ObjectFactory {
    private String userName;
    private int    id;

    /**
     * Getter method for property <tt>name</tt>.
     * 
     * @return property value of name
     */
    public final String getName() {
        return userName;
    }

    /**
     * Setter method for property <tt>name</tt>.
     * 
     * @param name value to be assigned to property name
     */
    public final void setName(String name) {
        this.userName = name;
    }

    /**
     * Getter method for property <tt>id</tt>.
     * 
     * @return property value of id
     */
    public final int getId() {
        return id;
    }

    /**
     * Setter method for property <tt>id</tt>.
     * 
     * @param id value to be assigned to property id
     */
    public final void setId(int id) {
        this.id = id;
    }

    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
                                    Hashtable<?, ?> environment) throws Exception {
        UserInfo userInfo = new UserInfo();
        Reference reference = (Reference) obj;
        Enumeration<RefAddr> cfgAddrs = reference.getAll();
        while (cfgAddrs.hasMoreElements()) {
            RefAddr cfgAddr = cfgAddrs.nextElement();
            String attrName = (String) cfgAddr.getType();
            String attrValue = (String) cfgAddr.getContent();
            if (attrName == "id") {
                userInfo.setId(Integer.valueOf(attrValue));
            } else if (attrName == "userName") {
                userInfo.setName(attrValue);
            }
        }
        return userInfo;
    }

}

从上面的代码可以看出,实例化对象时,容器会将配置的属性传递给回调函数,即第一个参数obj中包含的数据。


然后在context.xml中定义类,基本和数据源的配置类似,只是需要定义factory属性

<Resource name="jndi/userInfo"
		auth="Container"
		type="org.footoo.jspTest1.UserInfo"
		userName="jeff"
		id="12"
		factory="org.footoo.jspTest1.UserInfo"
		 />

然后只需要调用下面的方法就可以获得UserInfo的属性(原理和配置数据源一模一样)

 context = new InitialContext();

 UserInfo userInfo = (UserInfo) context.lookup("java:comp/env/jndi/userInfo");


关于JNDI的补充:

1、jndi本质就是通过factory(实现ObjectFactory接口的)类将配置的属性赋予目标对象

2、对于bean,我们甚至可以通过反射实现其属性的自动赋予。这个感觉就是spring的IOC了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值