JNDI理解与演示
环境只需要基本jdk包
先手动实现一个JNDI的服务。
抽象服务接口如下:
1 package loci.jndi;
2
3 /**
4 * @author yaohw
5 *
6 */
7 public interface JndiIService {
8
9 String fun();
10
11 String getField();
12
13 }
实现服务:注意需要实现Referenceable,重写getReference方法
package loci.jndi;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
/**
* @author yaohw
*
*/
public class JndiService implements Referenceable,JndiIService{
String field;
/* (non-Javadoc)
* @see javax.naming.Referenceable#getReference()
*/
@Override
public Reference getReference() throws NamingException {
//Reference是对象的引用,Context中存放的是Reference,为了从Reference中还原出对象实例,
//我们需要添加field,它们是创建对象实例的线索。在JndiService中,field是个线索。
Reference ref=new Reference(getClass().getName(),JndiServiceFactory.class.getName(),null);
ref.add(new StringRefAddr("field",field));
return ref;
}
/* (non-Javadoc)
* @see loci.jndi.JndiIService#fun()
*/
@Override
public String fun() {
// TODO Auto-generated method stub
System.out.println("test fun from jndi. field:"+field);
return field;
}
public void setProperty(int index,String property){
field=property;
}
/**
* @return the field
*/
public String getField() {
return field;
}
/**
* @param field the field to set
*/
public void setField(String field) {
this.field = field;
}
}
JndiServiceFactory的实现为:
1 import javax.naming.Context;
2 import javax.naming.Name;
3 import javax.naming.Reference;
4 import javax.naming.spi.ObjectFactory;
5
6 /**
7 * @author yaohw
8 *
9 */
10 public class JndiServiceFactory implements ObjectFactory {
11
12 /*
13 * (non-Javadoc)
14 * @see javax.naming.spi.ObjectFactory#getObjectInstance(java.lang.Object,
15 * javax.naming.Name, javax.naming.Context, java.util.Hashtable)
16 */
17 @Override
18 public Object getObjectInstance(Object obj, Name name, Context nameCtx,
19 Hashtable<?, ?> environment) throws Exception {
20 if (obj instanceof Reference) {
21 JndiService jndiService = new JndiService();
22 Reference ref=(Reference)obj;
23 String field = (String)ref.get("field").getContent();
24 jndiService.setProperty(0, field);
25 return jndiService;
26 }
27 return null;
28 }
29
30 }
服务已经准备好了,接下来就是注册到JNDI上,并从JNDI获取
注册过程在JndiContainer中完成:
package loci.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;
/**
* @author yaohw
*
*/
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中读取JndiService的实现,绑定到Context中。
private void loadServices() throws Exception {
InputStream in = getClass().getResourceAsStream("JndiContainer.properties");
Properties props = new Properties();
props.load(in);
// inject jndiservice
String s = props.getProperty("JndiServiceClass");
Object obj = Class.forName(s).newInstance();
if (obj instanceof JndiService) {
JndiService service = (JndiService) obj;
String[] ss = props.getProperty("JndiServiceProperty").split(";");
for (int i = 0; i < ss.length; i++)
service.setProperty(i, ss[i]);
ctx.rebind(props.getProperty("JndiServiceName"), service);
}
}
public void close() throws NamingException {
ctx.close();
}
public Context getContext() {
return ctx;
}
}
注册是从属性文件中读取注册信息:
##和JndiContainer.java文件位于同一目录
JndiServiceName=JndiService
JndiServiceClass=loci.jndi.JndiService
JndiServiceProperty="test"
测试使用JNDI:
1 package loci.jndi;
2
3 import javax.naming.Context;
4
5 /**
6 * @author yaohw
7 *
8 */
9 public class JndiClient {
10
11
12 public static void main(String[] args){
13 try{
14 JndiContainer container=new JndiContainer();
15 container.init();
16
17 //JNDI客户端使用标准JNDI接口访问命名服务。
18 Context ctx=container.getContext();
19 JndiIService jndiIService=(JndiIService)ctx.lookup("JndiService");
20 System.out.println("service field is:"+jndiIService.getField());
21 jndiIService.fun();
22 container.close();
23 }
24 catch(Exception e){
25 e.printStackTrace();
26 }
27 }
28 }