QLExpress脚本语言技术讲解(4)------扩展QLExpress来管理spring的bean,写出简单的脚本语言框架
2012-04-17 12:00
896 查看
类似淘宝、腾讯之类的复杂业务系统一般都采用分布式的系统集群结构,每一个独立的子系统负责一块业务,这样做主要是为了使业务更加分离,专人负责专人的应用系统,同时降低系统的耦合性,增强系统的安全和稳定性。同时分布式的数据库和应用结构,使很多复杂的业务规则也变成了一个特定的系统调用。
比如“支付订单(12781)”,需要调用一个交易中心的支付订单API。
本章主要介绍的是如何通过扩展QlExpress的上下文,来管理和调用spring的bean。以及在出现系统故障的时候,编写批量脚本来快速的恢复子系统的间系统调用。
我们来看这个场景:
对应的qlExpress的参数设置原理图:
![](http://my.csdn.net/uploads/201204/17/1334633384_2354.png)
这个控制台的界面大概是这样设计的:
问题是 QlExpress虽然可以解读orderService.orderPay(id)是个bean的方法调用,但是orderService这个bean怎么从spring获取到和脚本关联起来呢?
答案是扩展QlExpress原来的上下文。
上下文的扩展类,实现了 IExpressContext:
最终我们可以在resultMap看到类似这样的结果:
就简单的几个类实现一个很强大的java脚本语言执行工具,是不是很犀利呢!
PS:
因为本身QlExpressRunner本身不依赖spring,所以这个例子就不在QlExpress的源代码demo中,如果有疑问可以联系我,
旺旺:天樵
QQ:371754252
比如“支付订单(12781)”,需要调用一个交易中心的支付订单API。
本章主要介绍的是如何通过扩展QlExpress的上下文,来管理和调用spring的bean。以及在出现系统故障的时候,编写批量脚本来快速的恢复子系统的间系统调用。
我们来看这个场景:
例如因为处理订单流程的平台因为网络原因暂停了很多用户的流程,导致有一大堆的订单号等待处理(12781,12788,12312)。
对应的qlExpress的参数设置原理图:
![](http://my.csdn.net/uploads/201204/17/1334633384_2354.png)
这个控制台的界面大概是这样设计的:
**************************************************** 用户上下文:idList ={12781,12788,12312} *************************************************** 执行的脚本:orderService.orderPay(id); ***************************************************
问题是 QlExpress虽然可以解读orderService.orderPay(id)是个bean的方法调用,但是orderService这个bean怎么从spring获取到和脚本关联起来呢?
答案是扩展QlExpress原来的上下文。
上下文的扩展类,实现了 IExpressContext:
import java.util.HashMap; import java.util.Map; import org.springframework.context.ApplicationContext; import com.ql.util.express.IExpressContext; @SuppressWarnings("serial") public class QLExpressContext extends HashMap<String,Object> implements IExpressContext<String,Object>{ private ApplicationContext context; public QLExpressContext(ApplicationContext aContext){ this.context = aContext; } public QLExpressContext( Map<String,Object> aProperties,ApplicationContext aContext){ super(aProperties); this.context = aContext; } /** * 抽象方法:根据名称从属性列表中提取属性值 */ public Object get(Object name) { Object result = null; result = super.get(name); try{ if (result == null &&this.context!= null && this.context.containsBean((String)name)) { //如果在Spring容器中包含bean,则返回String的Bean result = this.context.getBean((String)name); } }catch(Exception e){ throw new RuntimeException(e); } return result; } public Object put(String name, Object object) { if(name.equalsIgnoreCase("myDbData")){ throw new RuntimeException("没有实现"); } return super.put(name,object); } }执行的工具类,实现了ApplicationContextAware 接口
import java.util.Map; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import com.ql.util.express.ExpressRunner; import com.ql.util.express.IExpressContext; import com.taobao.upp.sc.common.expression.QLExpressContext; public class QlExpressUtil implements ApplicationContextAware{ private static ExpressRunner runner ; static{ runner = new ExpressRunner(); } private static boolean isInitialRunner = false; private ApplicationContext applicationContext;//spring上下文 /** * * @param statement 执行语句 * @param context 上下文 * @throws Exception */ @SuppressWarnings("unchecked") public Object execute(String statement,Map<String,Object> context) throws Exception { initRunner(runner); IExpressContext expressContext = new QLExpressContext(context,applicationContext); statement = initStatement(statement); return runner.execute(statement, expressContext, null, true, false); } /** * 在此处把一些中文符号替换成英文符号 * @param statement * @return */ private String initStatement(String statement) { return statement.replace("(", "(").replace(")", ")").replace(";", ";").replace(",", ",").replace("“", "\"").replace("”", "\""); } private void initRunner(ExpressRunner runner) { if(isInitialRunner == true){ return ; } synchronized (runner) { if(isInitialRunner == true){ return ; } try { //在此可以加入预定义函数 } catch (Exception e) { throw new RuntimeException("初始化失败表达式",e); } } isInitialRunner = true; } public void setApplicationContext(ApplicationContext aContext) throws BeansException { applicationContext = aContext; } }
import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.map.ListOrderedMap; 控制台代码的实现 public class ClientQlExpressTest { /** * * @param idList * @param text * @param resultMap */ public void run(List<Long> idList, String text, ListOrderedMap resultMap) { for (Long id : idList) { Map<String, Object> innerContext = new HashMap<String, Object>(); innerContext.put("id", id); Object result = qlExpressUtil.execute(statement, innerContext); resultMap.put(id, result); } } }
最终我们可以在resultMap看到类似这样的结果:
12781 | true |
12788 | false |
12312 | true |
orderService.orderPay(id);这个脚本虽然对于java开发工程师师没有问题的,但是对于技术支持人员,显然还是太难记住了,下篇我们将进行宏定义,变成
支付订单(id)
PS:
因为本身QlExpressRunner本身不依赖spring,所以这个例子就不在QlExpress的源代码demo中,如果有疑问可以联系我,
旺旺:天樵
QQ:371754252
相关文章推荐
- QLExpress脚本语言技术讲解(6)-------QLExpress的缓存管理
- QLExpress脚本语言技术讲解(1)
- QLExpress脚本语言技术讲解(3) -----QL的性能描述
- QLExpress脚本语言技术讲解(5)------对脚本语言的进一步优化,变成中文的脚本语言
- QLExpress脚本语言技术讲解(2) -----QL的基本执行过程
- 【SSH三大框架】Spring基础第一篇:搭建Spring环境、实例化Bean、管理Bean的作用域以及Bean的生命周期
- Java框架spring 学习笔记(九):Spring的bean管理(@Required、@Component、@Autowired、@Resource注解)
- CXF框架简单的JavaBean对象传递进行讲解。
- 自行控制loadrunner的socket协议性能测试 (转) 一前言 二任务的提出 三实现方案讨论 四技术要点讲解 如何开始录制一个最简单的收发数据包脚本 写日志文件 一行一行读数据包文件 字
- 简单模型剖析Spring管理Bean的原理
- 使用Jena RDF API 开发脚本语言管理资源描述框架模型
- ns2脚本语言Tcl的扩展语言Otcl简单介绍<2>
- ssm框架创建简单的DVD管理系统(四)spring的配置与mybatis的配置
- 框架学习之Spring 第二节 采用Spring管理Bean和依赖注入
- 《Spring 2.0技术手册》 读书笔记七-Spring的DAO框架(3)-JDBC事务管理
- ppst——技术视频spring AOP 的原理讲解和简单实现
- 框架学习之Spring 第二节 采用Spring管理Bean和依赖注入
- 《Spring 2.0技术手册》 读书笔记七-Spring的DAO框架(3)-JDBC事务管理
- 深入探索spring技术内幕(二): 剖析spring管理Bean的原理与配置
- java开发web工程有 servlet/ jsp/ spring mvc等技术框架,那其他语言呢?