本文对ESS中使用EJB来实现分布式应用,进行了初步的控析,为方便描述,提供了一个简单的伪码例子
1,ESS中 ESSEJBFBS为 部署EJB3.0的工程
ESSWEBFBS为WEB工程,其中的JAVA类,对ESSEJBFBS中部署的EJB 进行了调用。
2,下面,我们从最简单的EJB3.0开始创建
ESSEJBFBS 应该包含以下二个JAVA类来实现EJB3.0
1) 接口:LiteralBeanRemote.JAVA
package com.liu.ejbdemo;
import javax.ejb.Remote;
@Remote
public interface LiteralBeanRemote {
public String correctLiteral(String agrs);
}
2) 具体业务实现类 LiteralBean.java
package com.liu.ejbdemo;
import javax.ejb.Stateless;
@Stateless(mappedName="Literal")
public class LiteralBean implements LiteralBeanRemote {
// Bean的真正实现部分.
public Map processBiz(EjfContext ejfContext, Map in){
// 做一些实际的业务 TAG 1
return NEW HASHMAP();
}
}
3 ESSWEBFBS中 Demo.java中对EJB业务类LiteralBean进行调用
(当然,此时发布时,要有ESSEJBFBS中的接口类)。
package com.liu.ejbdemo;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
public class Demo {
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
props.setProperty(Context.PROVIDER_URL,"t3://127.0.0.1:7001");
try {
InitialContext ctx = new InitialContext(props);
LiteralBeanRemote myHello = (LiteralBeanRemote) ctx.lookup("Literal#com.liu.ejbdemo.LiteralBeanRemote");
// 调用EJB业务类
MAP thers = myHello.processBiz(ejfContext, in);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
4 上面的2 3 步,初步实现了EJB的功能,然而,对一个大弄系统来说,这个通用性不好,于是,下面进行改写
首先对LiteralBean.java进行改写
因为LiteralBean.java中的processBiz只能实现一个业务的处理,所以我们对其进行扩展,让processBiz
中的传入参数ejfContext.BizServiceTarget中包含一个字符串如:com.ailk.ess.fbs.business.numdiscard.service.FbsNumDiscardService.orderNumQuery
其中FbsNumDiscardService为类名,orderNumQuery为类中的一个方法,
processBiz中的传入参数IN,为这个orderNumQuery方法的传入参数。
因此processBiz中,我们利用反射,执行orderNumQuery方法,即可对该类完成了扩展
// 做一些实际的业务 TAG 1 替换为:
伪码如下:
String serviceTarget = ejfContext.get_BizServiceTarget();
String className = StringUtils.substringBeforeLast(serviceTarget, ".");
String methodName = StringUtils.substringAfterLast(serviceTarget, ".");
Class cls = getClassLoader().loadClass(className);
Method method = MethodUtils.getAccessibleMethod(cls, name, parameterTypes);;
return method.invoke(ClassUtils.newInstance(cls), in)
5 然后我们再对Demo.java 进行改写,来实现代码的优化
我们先生成一个配置文件,如下行,并将其读到route中
*, D, com.linkage.ess.ejb.BsdEJBRemote, t3://10.142.131.1:8006
并加入env项
route.provinceCode = *;
route.zoneCode = D;
route.useEjb = true;
route.remoteClass = com.liu.ejbdemo.LiteralBeanRemote
route.ejbCallShortName = Literal
route.providerUrl = t3://10.142.131.1:8006
env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.setProperty(Context.PROVIDER_URL, route.providerUrl);
route.env = env;
这样,当Demo.java运行时,我们可以根据运行Demo.java实例时客户的zoneCode来载入不同的route
然后根据providerUrl生成不同的InitialContext、LiteralBeanRemote
(providerUrl不同,生成的LiteralBeanRemote引用为在不同的机器上的LiteralBean实例)
6 实际的系统中,不仅只有Literal,还有FBS BSD 等工程,所以对代码进行了进一步改写,以支持不同工程名
下的EJB,进而也需要对LiteralBeanRemote LiteralBean 进行改写,LiteralBean提取出一个父类,
来支持不同工程下的EJB实现。
当然,还有一些其它细节,未完待续。。。