公司的platform产品中用到了基于EJB的工作流,而platform每次调用工作流时,都是通过JNDI对home接口进行lookup,这个动作是很耗性能的,而以前竟然没有进行缓存,汗ing........,刚刚看到了Brett McLaughlin写的一篇<<
EJB 最佳实践:工业强度的 JNDI 优化>> 于是赶紧改写了一个home接口的工厂类:
EJBHomeFactory.java
public class EJBHomeFactory {
private static Log log = Logger.getLog(EJBHomeFactory.class);
/**
* EJBHOME和JNDI参数,直接取得连接时使用
*/
private static final String WORKLIST_JNDI = "com.company.workflow.engine.worklist.Worklist";
private static final String WORKLIST_HOME = "com.company..workflow.engine.worklist.WorklistHome";
private static final String ADMIN_JNDI = "com.company.workflow.engine.admin.Admin";
private static final String ADMIN_HOME = "com.company..workflow.engine.admin.AdminHome";
private static final String DEFINITION_JNDI = "com.company..workflow.definition.Definition";
private static final String DEFINITION_HOME = "com.company..workflow.definition.DefinitionHome";
private static String url;
private static String userID;
private static String password;
private Map ejbHomes;
Context ctx;
/** 对象本身 */
private static EJBHomeFactory m_singleton;
static
{
url = Config.getString("workflow.jndi.provider.url", null);
userID = Config.getString("workflow.jndi.security.principal", null);
password = Config.getString("workflow.jndi.security.credentials", null);
}
protected EJBHomeFactory() throws NamingException,WorkflowApplicationException{
ctx = getInitialContext();
ejbHomes = Collections.synchronizedMap(new HashMap());
}
/**
* 返回唯一的静态对象(Singleton模式)
* @return EJBHomeFactory
* @throws NamingException 调用new InitialContext()失败时,返回嵌套了一个NamingException的工作流异常
*/
public static EJBHomeFactory getInstance() throws NamingException,WorkflowApplicationException{
if ( m_singleton == null)
m_singleton = new EJBHomeFactory();
return m_singleton;
}
public EJBHome lookUpHome(String jndiName,String homeName) throws NamingException,WorkflowApplicationException {
//先从缓存中取得home接口
EJBHome homeInterface = (EJBHome)ejbHomes.get(homeName);
//如果缓存中不存在,则用jndi进行查找
if (homeInterface == null)
{
try
{
Object obj = ctx.lookup(jndiName);
homeInterface =
(EJBHome)PortableRemoteObject.narrow(obj, Class.forName(homeName));
//将home接口放入缓存中
ejbHomes.put(homeName, homeInterface);
}
catch (Exception e)
{
log.error("查找home接口出错", e);
throw new WorkflowApplicationException("不能获得home接口:" +
e.getMessage());
}
}
return homeInterface;
}
private Context getInitialContext() throws WorkflowApplicationException
{
Context context = null;
try
{
Properties prop = new Properties();
prop.put(Context.INITIAL_CONTEXT_FACTORY,
Config.getString("workflow.jndi.factory.initial", null));
prop.put(Context.PROVIDER_URL,url);
if (userID != null)
{
prop.put(Context.SECURITY_PRINCIPAL, userID);
prop.put(Context.SECURITY_CREDENTIALS, password);
}
context = new InitialContext(prop);
}
catch (Exception e)
{
log.error("初始化服务context出错", e);
throw new WorkflowApplicationException(e.getMessage());
}
return context;
}
/**
* 获取Definition的Home接口
* @return Definition的Home接口
* @throws NamingException 如果发生工作流应用异常
*/
public final DefinitionHome getDefinitionHome() throws NamingException,WorkflowApplicationException{
return (DefinitionHome)m_singleton.lookUpHome(DEFINITION_JNDI,DEFINITION_HOME);
}
/**
* 获取Admin的Home接口
* @return Admin的Home接口
* @throws NamingException 如果发生工作流应用异常
*/
public final AdminHome getAdminHome() throws NamingException,WorkflowApplicationException{
return (AdminHome)m_singleton.lookUpHome(ADMIN_JNDI,ADMIN_HOME);
}
/**
* 获取Worklist的Home接口
* @return Worklist的Home接口
* @throws NamingException 如果发生工作流应用异常
*/
public final WorklistHome getWorklistHome() throws NamingException,WorkflowApplicationException{
return (WorklistHome)m_singleton.lookUpHome(WORKLIST_JNDI,WORKLIST_HOME);
}
- 作者:
snowfox2008 2004年07月16日, 星期五 10:35