java8 基于lambda的AOP切面小试

废话不多说,直接上代码.
比如说以下是Controller中一个新增订单的方法

    /**
     * 新增订单
     */
    public void newOrder() {
        logger.info("go into UnifyOrderController addNewOrder method");
        BaseResult br = new BaseResult();
        Map<String, String> params = ThreadLocalContextManager.getRequestInfo().getContent().getParamContent();
        try {
	        /**
	        此处省略动态数据源获取等业务无关代码
	        **/
            factory.addNewOrder(params);
        } catch (RemoteExecuteException e) {
            br.setCode(RespCode.FAIL.getStrCode());
            br.setMsg(e.getMessage());
        } catch (Exception e) {
            br.setCode(RespCode.SYSTEM_ERROR.getStrCode());
            br.setMsg(RespCode.SYSTEM_ERROR.getMsg());
        }
        logger.info("go out UnifyOrderController addNewOrder method");
        //输出结果
        responseJson(br);
    }

无关业务的代码有:写日志,获取参数,动态数据源,异常处理等。
而业务代码就

 factory.addNewOrder(params);

一行,但是洋洋洒洒好多行,分外不爽。

以下就基于lamda 表达式来实现下代码切面。
lambda 函数式编程,可以让方法作为一个参数传入。从而把业务无关的共通代码封装起来,而把业务代码作为参数传进去,以实现切面的功能。

以下是详细步骤:

1.定义一个函数式接口

public interface CommonExcute {
    void exctue(Map<String, String> params) throws Exception;
}

2.把业务无关代码封装成共通代码,可以写在父类里面,子类继承。

	public class BaseController {
    /**
     * 共通执行方法
     * @param commonExcute
     */
    	public void setResponse(CommonExcute commonExcute) {
	        RetailResult<String> result = new RetailResult<>();
	        result.setCode(RespCode.SUCCESS.getCode());
	        result.setMsg(RespCode.SUCCESS.getMsg());
	        result.setData(OK);
	        try {
		        /**
		        此处省略动态数据源获取等业务无关代码
		        **/
	            Map<String, String> params = ThreadLocalContextManager.getRequestInfo().getContent().getParamContent();
	            logger.info("result:{}",JSONObject.toJSONString(params));
	            //lambda 预留执行方法 
	            commonExcute.exctue(params);
	        }catch (RemoteExecuteException e) {
	            result.setCode(Integer.valueOf(e.getCode()));
	            result.setMsg(e.getMessage());
	        } catch (Exception e) {
	            result.setCode(RespCode.SYSTEM_ERROR.getCode());
	            result.setMsg(RespCode.SYSTEM_ERROR.getMsg());
	        }
	        logger.info("result:{}",JSONObject.toJSONString(result));
	        responseJson(result);
    	}
    }

3.把业务代码作为参数传进去

	public class ChildController extends BaseController {
	    /**
	     * 新增新订单信息
	     */
	    public void addNewOrder() {
	        logger.info("addNewOrder method");
	        setResponse((Map<String, String> params)->{
	            factory.addNewOrder(params);
	        });
    	}
    }

短短几行,只需要关心业务代码,清爽搞定。这样只要把业务代码通过lambda传入setResponse即可。
不需要关心异常处理,动态数据源以及参数获取,参数结果日志打印等等业务无关代码。
作为强迫症患者,舒服多了。

本文只是以lambda方式实现,其它实现方式还有很多,可以用代理模式或者用 spring框架的aop配置等。

你可能感兴趣的:(开发笔记)