qlExpress实践手册-spring的融合

来源:互联网 发布:营销qq群发软件 编辑:程序博客网 时间:2024/05/22 15:10

中国绝大部分java应用系统都使用spring作为基础系统架构的一部分。
对于qlExpress脚本引擎来说,能否调用spring bean的方法?怎么调用?是一个非常常见的问题。
以下通过案例来说明。有问题请联系
微信 371754252
或者邮件 tianqiao@taobao.com

比如说你要执行以下的一段qlExpress脚本,除了orderId等普通变量,
还需要传入 bizOrderDao,tradeHsfBean,refundHsfBean 等spring bean变量。

order = bizOrderDao.getOrderById(orderId);if(order.status==2){return tradeHsfBean.syncOrder(order);}else{return refundHsfBean.syncOrder(order);}return null;

方案1:手工注入bean

public void test(){    ExpressRunner runner = new ExpressRunner();    DefaultContext<String, Object> context = new DefaultContext<String, Object>();    Context.put(“orderId”,100012L);    Context.put(“bizOrderDao”,getSpringBean("bizOrderDao"));    Context.put(“tradeHsfBean”,getSpringBean("tradeHsfBean"));    Context.put(“refundHsfBean”,getSpringBean("refundHsfBean"));    Object result = runner.execute(text, context, null,true, false);    system.out.println(result);}

方案2:扩展上下文,自动注入bean

解决方案:把DefaultContext升级为SpringBeanContext

public class SpringBeanContext extends HashMap<String,Object>implements IExpressContext<String,Object> {    private ApplicationContext applicationContext;    Public SpringBeanContext(Map<String,Object> aProperties,ApplicationContext applicationContext)    {        super(aProperties);        this.applicationContext = applicationContext;    }    /**    * 根据key从容器里面获取对象    *    * @param key    * @return    */    public Object get(Object key) {        Object object = super.get(key);        try {            if (object == null && this.applicationContext != null                && this.applicationContext.containsBean((String)key))            {                object = this.applicationContext.getBean((String)key);            }        } catch (Exception e) {            throw new RuntimeException("表达式容器获取对象失败", e);        }        return object;    }    /**    * 把key-value放到容器里面去    *    * @param key    * @param value    */    public Object put(String key, Object value) {        return super.put(key, value);    }}@Servicepublic SpringBeanRunner implements ApplicationContextAware{    private ApplicationContext applicationContext;    private ExpressRunner runner;    @override    public void setApplicationContext(ApplicationContext context) {        this.applicationContext = context;        runner = new ExpressRunner();    }    public Object executeExpress(String text,Map<String,Object> context)    {        IExpressContext<String,Object> expressContext = new SpringBeanContext(context,this.applicationContext);        try{            return runner.execute(text, expressContext, null, true, false);        }catch(Exception e){            logger.error("qlExpress运行出错!",e);        }        return null;    }}

至此,通过对runner的简单封装,你现在只要直接使用这样的代码就可以轻松完成你对bean的调用了。

@Resourceprivate SpringBeanRunner runner;public void test(){    Map<String, Object> context = new HashMap<String, Object>();    Context.put(“orderId”,100012L);     Object result = runner.executeExpress(text, context);    system.out.println(result);}

附录:你可能会遇到的坑

1、bean取出来为空

检查下applicationContext里面,对应的com.taobao.XXXX.BizOrderDAO名称是否真的是“bizOrderDAO”

(1)spring注解问题

spring的默认注解使用byType,在applicationContext不是名称,请指定name或者使用ByName

@Service("tradeHsfBean")public class TradeHsfBean{}

(2)ApplicationContext注入失败

SpringBeanRunner没有调用到setApplicationContext(ApplicationContext context) 方法,请调试一下。

阅读全文
0 0
原创粉丝点击