目前我使用以下代码来查找正常POJO类的EJB3 sateless会话bean。 (我们在JEE5中所以我们不能在正常的POJO类中注入无状态会话Bean我必须使用查找)
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.log4j.Logger;
public Object getEJB(String jndiName) {
logger.debug("WEBSPHERE EJB Lookup : " + jndiName);
String modifiedJndiName = "";
Hashtable<Object, Object> properties = new Hashtable<Object, Object>();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
properties.put(Context.PROVIDER_URL, "iiop://localhost:2809");
try {
Context context = new InitialContext(properties);
logger.debug("WEBSPHERE EJB Lookup Modified JNDI Name: " + modifiedJndiName);
return context.lookup("ejblocal:"+modifiedJndiName);
}catch (NamingException ne) {
logger.debug("Naming Exception occurred :"+jndiName +">>>"+ne.getMessage());
logger.error(ne.getMessage(), ne);
}
return null;
}
Context对象是ThredSafe吗?我应该为每个调用创建Context对象[如此代码片段所示],还是我可以为所有线程重用Context?
答案 0 :(得分:15)
关于线程安全的答案通常在javadoc中已经提到,只要相关。事实上,InitialContext
javadoc提到了以下内容:
InitialContext
实例未与多个线程的并发访问同步。每个操作不同InitialContext
实例的多个线程无需同步。需要同时访问单个InitialContext
实例的线程应该在它们之间进行同步并提供必要的锁定。
最后一句确认了它:它不是线程安全的,并且每线程同步是必要的。但是,在您的特定代码示例中,不需要同步,因为它始终在方法本地范围内创建(即它绝对不在线程之间共享)。如果您的特定代码示例中的InitialContext
是实例变量,那么您必须将synchronized
关键字添加到getEJB()
方法。
答案 1 :(得分:0)
但是如果我把这个方法放在单例类中,那么我可以使用Context作为类变量吗?就像下面的代码方法在单例ServiceLocator
类中一样。
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class ServiceLocator {
static volatile ServiceLocator serviceLocator = null;
Map supportedAppServerMap = null;
@Override
public Object getEJB(String jndiName) {
logger.debug("WEBSPHERE EJB Lookup : " + jndiName);
String modifiedJndiName = "";
Hashtable<Object, Object> properties = new Hashtable<Object, Object>();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
properties.put(Context.PROVIDER_URL, AMPPropertyUtil.getProperty("PROVIDER_URL"));
try {
Context context = new InitialContext(properties);
if (null != jndiName && jndiName.indexOf(".") != -1)
modifiedJndiName = jndiName.substring(jndiName.lastIndexOf(".") + 1);
else
modifiedJndiName = jndiName;
logger.debug("WEBSPHERE EJB Lookup Modified JNDI Name: " + modifiedJndiName);
return context.lookup("ejblocal:" + modifiedJndiName);
} catch (NamingException ne) {
logger.debug("Naming Exception occurred :" + jndiName + ">>>" + ne.getMessage());
logger.error(ne.getMessage(), ne);
}
return null;
}
@Override
public DataSource getDataSource() {
Context context = null;
final String dsName = AMPPropertyUtil.getProperty("dsName");
Hashtable<Object, Object> properties = new Hashtable<Object, Object>();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
properties.put(Context.PROVIDER_URL, AMPPropertyUtil.getProperty("PROVIDER_URL"));
try {
context = new InitialContext();
return (DataSource) context.lookup("java:comp/env/" + dsName);
} catch (NamingException e) {
logger.error(e.getMessage(), e);
}
return null;
}
@Override
public Object getResources(final String jndiName) {
Context context = null;
Hashtable<Object, Object> properties = new Hashtable<Object, Object>();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
properties.put(Context.PROVIDER_URL, AMPPropertyUtil.getProperty("PROVIDER_URL"));
try {
context = new InitialContext();
return context.lookup(jndiName);
} catch (NamingException e) {
logger.error(e.getMessage(), e);
}
return null;
}
public static ServiceLocator getInstance() {
if (serviceLocator == null) {
synchronized (ServiceLocator.class) {
if (null == serviceLocator)
serviceLocator = new ServiceLocator();
}
}
return serviceLocator;
}
}