类似淘宝、腾讯之类的复杂业务系统一般都采用分布式的系统集群结构,每一个独立的子系统负责一块业务,这样做主要是为了使业务更加分离,专人负责专
人的应用系统,同时降低系统的耦合性,增强系统的安全和稳定性。同时分布式的数据库和应用结构,使很多复杂的业务规则也变成了一个特定的系统调用。
比如“支付订单(12781)”,需要调用一个交易中心的支付订单API。
本章主要介绍的是如何通过扩展QlExpress的上下文,来管理和调用spring的bean。以及在出现系统故障的时候,编写批量脚本来快速的恢复子系统的间系统调用。
我们来看这个场景:
例如因为处理订单流程的平台因为网络原因暂停了很多用户的流程,导致有一大堆的订单号等待处理(12781,12788,12312)。
对应的qlExpress的参数设置原理图:
这个控制台的界面大概是这样设计的:
****************************************************
用户上下文: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 |
就简单的几个类实现一个很强大的java脚本语言执行工具,是不是很犀利呢!
orderService.orderPay(id);
这个脚本虽然对于java开发工程师师没有问题的,但是对于技术支持人员,显然还是太难记住了,下篇我们将进行宏定义,变成
支付订单(id)
PS:
因为本身QlExpressRunner本身不依赖spring,所以这个例子就不在QlExpress的源代码demo中,如果有疑问可以联系我,
旺旺:天樵
QQ:371754252
分享到:
相关推荐
【脚本技术script56--2006】是一本专注于脚本技术的电子书籍,以CHM(Microsoft ...虽然时间已过去多年,但许多脚本语言的基本原理和技术依然适用,对于初学者和有经验的开发者来说,这仍是一份有价值的参考资料。
简单明了的shell脚本语言讲义,让你轻松了解shell语言。
BAT批处理脚本-WinXP相关批处理-12个 BAT批处理脚本-加密解密-22个 BAT批处理脚本-实用的批处理文件-70个 BAT批处理脚本-提示窗口进度条-17个 BAT批处理脚本-数值计算-23个 BAT批处理脚本-文件相关操作-92个 BAT...
10. **可扩展性**:QLExpress可能支持插件系统或模块化设计,允许用户通过添加第三方库来扩展其功能,满足特定项目需求。 在实际应用中,QLExpress可以用于快速构建原型、自动化任务、数据分析、Web服务接口等。...
总的来说,Spring Boot CLI为初学者提供了一个快速尝试Spring Boot功能的平台,通过简单的命令行操作就能创建和运行应用程序。2.0.3.RELEASE版本的稳定性确保了开发过程的顺畅,而且Groovy的简洁语法使得学习曲线...
它通过读取配置元数据(XML、Java注解或Groovy脚本)来初始化和管理对象。 3. **AOP**: - AOP允许开发者定义“方面”,这些方面封装了横切关注点,如日志记录、事务管理等。Spring AOP支持使用代理模式实现切面,...
3. **支持Java配置**:除了XML配置外,Spring 3.0引入了Java配置,允许开发者使用注解和Java类来定义bean的配置,提高了代码的可读性和可测试性。 4. **Groovy支持**:Spring 3.0增加了对Groovy的支持,允许开发者...
IoC容器通过控制反转原则来管理对象的创建和依赖关系解析,Bean工厂负责创建和维护应用程序中对象的生命周期。Resource抽象则负责封装底层资源访问,而验证模块则提供了支持数据验证的方法和工具。 资源管理是...
《Spring Test 3.2.0.RELEASE:深入理解与应用》 在Java开发领域,Spring框架以其强大的功能和灵活性,成为了企业级应用的首选。其中,`spring-test`模块是Spring框架的一部分,专为集成测试提供了一整套工具和支持...
8. **脚本语言支持**:Spring Boot CLI默认支持Groovy作为编程语言,Groovy是一种简洁且动态的Java平台语言,语法简洁,易于学习。此外,还可以通过插件支持Java和Kotlin等其他语言。 9. **插件系统**:CLI支持插件...
- **安装**: 安装 Spring Boot 非常简单,可以通过 Maven、Gradle 等构建工具或者使用 Spring Boot CLI 来安装。Maven 是 Java 生态中最常用的构建工具之一,而 Gradle 则是一种新兴的构建工具,其自动化的依赖管理...
4. **Groovy/Grails支持**:Grails是基于Groovy语言的Web开发框架,STS提供了良好的集成,便于使用Grails进行开发。 5. **Spring Boot支持**:STS对Spring Boot有深度集成,包括启动器向导、配置编辑器以及Actuator...
《Spring JDBC 4.2.xsd详解》 在Java企业级开发中,Spring框架是不可或缺的一部分,它提供了全面的编程和配置模型,极大地简化了应用的构建和维护。Spring JDBC作为Spring框架的一部分,主要负责数据库操作,使得...
Spring Flex 是一个开源项目,它提供了Spring框架与Adobe Flex之间的集成,使得开发人员可以利用Spring的强大功能来构建富互联网应用程序(RIAs)。Flex是用于创建交互式、高性能的基于Web的用户界面的平台,而...
- 在命令行中,可以直接编写并运行Groovy脚本,Groovy是Spring Boot CLI的默认脚本语言。 - 例如,键入`spring run HelloWorld.groovy`,其中`HelloWorld.groovy`是包含Spring Boot应用逻辑的脚本。 4. **开发...
2. JPA与Hibernate:Spring Boot 1.5.3.RELEASE对JPA和Hibernate的支持更加完善,包括实体管理、事务控制和查询语言等。 五、Spring Boot CLI 1. Spring Boot命令行接口(CLI):提供了快速试用和开发Spring Boot...
- Groovy脚本可以利用Spring Boot的所有功能,包括自动配置、Bean定义等。 4. **自动化脚本** - Spring Boot CLI特别适合创建自动化脚本,例如持续集成任务或自定义构建步骤。 - 用户可以编写Groovy脚本来处理...
maxscript语言是3ds max 自带的脚本语言,它不但拥有一般程序语言的所有特点,而且可以在程序内实现几乎所有在3ds max界面下的交互操作,功能非常强大,而且语法比较简单,容易上手。. 本书详细、系统地介绍了max...
linux服务器,springboot,spring cloud、spring cloud alibaba等项目启动脚本 下载脚本, 1,上传脚本至jar包同级目录 2,更改脚本: jar包名称 项目文件路径 日志路径(包含日志名称) 脚本已配置好jvm优化...