QLExpress來管理spring的bean (三)

目的

有些特定的場景,我們需要讓QLExpress幫我們調用某個bean(比如dao執行sql或者某個service執行業務代碼),這個時候我們需要拿到dao或者service,因爲QLExpress本身是不依賴spring的,所以需要對QLExpress做擴展,讓它可以管理bean,這樣就可以滿足更多的需求啦

場景

根據優惠券ID查詢優惠券詳細信息

couponCardOpenService.queryCouponCardByCardId(QueryCouponCardByCardIdRequest)
couponCardOpenService是外部的dubbo服務,我們把這個方法調用封裝成自己的一個bean方法調用,封裝後的代碼如下:
public interface YhManager {

     BaseResponse<CouponCardDto> getCouponCardById(Long cardId);
}

@Service(value="YhManager ")
public class YhManager Impl implements YhManager {

    private static final Logger logger = LoggerFactory.getLogger(MdsManagerImpl.class);
    @Reference
    private CouponCardOpenService couponCardOpenService;
    
    @Override
    public BaseResponse<CouponCardDto> getCouponCardById(Long cardId) {
        QueryCouponCardByCardIdRequest QueryCouponCardByCardIdRequest = new QueryCouponCardByCardIdRequest();
        QueryCouponCardByCardIdRequest.setCardId(cardId);
        return couponCardOpenService.queryCouponCardByCardId(QueryCouponCardByCardIdRequest);
    }
}

封裝成本地bean的調用方法是爲了方便通過

applicationContext.getBean(MdsManager.class)獲取MdsManager這個bean

因爲如果直接獲取CouponCardOpenService這個外部bean的話會取不到;

 

擴展管理bean

使用IExpressContext進行擴展QLExpressContext,重寫get和put方法
public class QLExpressContext extends HashMap<String,Object> implements IExpressContext<String,Object> {

    private ApplicationContext context;
    public QLExpressContext(Map<String,Object> aProperties, ApplicationContext aContext){
        super(aProperties);
        this.context = aContext;
    }
    /**
     * 根據key從容器裏面獲取對象
     *
     * @param key
     * @return
     */
    public Object get(Object key) {
         Object object = super.get(key);
         try {
             if (object == null && this.context != null && this.context.containsBean((String)key)) {
                 object = this.context.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); }

}

利用ApplicationContextAware 來獲取ApplicationContext上下文

@Service
public class QlExpressRunner implements ApplicationContextAware {
    private Logger logger = LoggerFactory.getLogger(QlExpressRunner.class);

    private ApplicationContext applicationContext;
    private ExpressRunner runner;

    @Override
    public void setApplicationContext(ApplicationContext context) {
        this.applicationContext = context;
        if(runner == null){
            runner = new ExpressRunner();
            logger.info("runner = new ExpressRunner()");
        }
    }
    public Object execute(String text,Map<String,Object> context) {
        IExpressContext<String,Object> expressContext = new QLExpressContext(context,this.applicationContext);
        try{
            //此處可以初始化宏函數.....
            //addFunctionOfServiceMethod
            runner.addFunctionOfServiceMethod("根據cardId查詢優惠券card信息",applicationContext.getBean(MdsManager.class),"getCouponCardById",new Class[]{Long.class},null);
            return runner.execute(text, expressContext, null, true, false);
        }catch(Exception e){
            logger.error("qlExpress運行出錯!",e);
        } return null;
    }

}

IExpressContext<String,Object> expressContext = new QLExpressContext(context,this.applicationContext);
 runner.addFunctionOfServiceMethod("根據cardId查詢優惠券card信息",applicationContext.getBean(MdsManager.class),"getCouponCardById",new Class[]{Long.class},null);

這樣就可以完美地取到applicationContext了;

調用代碼:

String statement = "根據cardId查詢優惠券card信息(c)";
Long cardId = 3164l;
Map<String, Object> innerContext = new HashMap<String, Object>();
innerContext.put("c",cardId);
Object result;
result = runner.execute(statement, innerContext);
System.out.println(JSON.toJSON(result));

表達式”根據cardId查詢優惠券card信息(c)“其實就是告訴了QLExpress執行

yHManager.getCouponCardById(id);

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章