博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
反射?切面?怎样对公共参数及行为进行封装
阅读量:6581 次
发布时间:2019-06-24

本文共 4100 字,大约阅读时间需要 13 分钟。

  现在都是微服务化访问,某系统访问另一系统时,总有一些公用参数需要处理,另外还需要对访问情况进行日志打印。

  调用的服务是dubbo服务,如何封装这一些公共参数而不是每次调用方法时都做反复的事呢?
三个方法:
  1. 写一个公共方法,在调用rpc方法前和方法后,都进行调用;
    简单直接且易读,且想加就加更灵活。不好处就是每个地方都要重复写这两段公用代码,不简洁。
  2. 使用反射方法,进行调用dubbo方法,在调用前调用后,都进行参数组装,并将日志打印好。
    好处是每次只需调用一个反射封装方法,就能完成所有工作,简单实用。坏处是方法被反射调用后,不直观,无法使用ide的语法检查快速发现潜在问题。
  3. 使用切面进行设值处理。
    好处是代码无侵入,简洁明了。坏处是新来的同学不易理解一些运行原理,不能很好利用切面辅助,另外,切面规则需要保持一致,否则无法实现处理。
来几个实现的例子吧!
使用公共方法:

// 公用封装参数方法,四处调用,当然这里是不完整的封装,可能还需要更复杂的代码侵入    public static void wrapCommonField(Object param) {        ThreadlocalVar session = ThreadlocalVar.getVar();        if (null != param && (param instanceof BaseDTO)) {            BaseDTO basePara = (BaseDTO) param;            if (null != session) {                basePara.setIp(session.getIp());                if(session.getUserId() != null) {                    basePara.setUserId(session.getUserId());                }            }        }        // ...    }// 调用,在调用service方法时,先鲁一段该调用代码    public static void main(String[] args) {        RpcServiceA serviceA = new RpcServiceA();        Object param = ...;        wrapCommonField(param);        // ...    }

 

使用反射:

// 公用反射方法    public static 
T callMethod(Object service, String mName, Object param) { ThreadlocalVar session = ThreadlocalVar.getVar(); if (null != param && (param instanceof BaseDTO)) { BaseDTO basePara = (BaseDTO) param; if (null != session) { basePara.setIp(session.getIp()); if(session.getUserId() != null) { basePara.setUserId(session.getUserId()); } } } Class
rpcServiceClass = service.getClass(); logger.info("call method:{},param:{}", mName, param); try { Method method = rpcServiceClass.getMethod(mName, new Class[] { param.getClass() }); ResponseResult
re = (ResponseResult
) method.invoke(rpcService, new Object[] { param }); logger.info("result:{}", re); if (null == re || !"1111".equals(re.getCode())) { throw new RuntimeException(re.getCode(), re.getMsg()); } return re.getData(); } catch (NoSuchMethodException | InvocationTargetException e) { logger.error("exception:{}", e); throw e; } catch (SecurityException | IllegalAccessException | IllegalArgumentException e) { logger.error("exception:{}", e); throw e; } }// 调用 public static void main(String[] args) { RpcServiceA serviceA = new RpcServiceA(); Object param = ...; callMethod(serviceA, "giveMeFive", param); // ... }

 

使用切面:

// 完整切面类,独立@Order(1)@Component@Aspectpublic class SignLoginAop {    private Logger logger = LoggerFactory.getLogger(getClass());        public static final String CALLAPI_POINT = "execution(* com.xx.api.web.d.*.*(..))";        @Around(CALLAPI_POINT)    public Object validSign(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException, KydException {        Object retVal = null;                Object[] args = pjp.getArgs();        Object param = (null != args && args.length > 0) ? args[0] : null;        if (null != param && (param instanceof BaseDTO)) {            BaseDTO basePara = (BaseDTO) param;            ThreadlocalVar session = ThreadlocalVar.getSession();            BaseDTO basePara = (BaseDTO) param;            if (null != session) {                basePara.setIp(session.getIp());                if(session.getUserId() != null) {                    basePara.setUserId(session.getUserId());                }            }        }        Signature signature = pjp.getSignature();        try {            logger.info("call method {}, param:{}", signature, args);            retVal = pjp.proceed(args);            logger.info("end method {}, retVal:{}", signature, retVal);        } catch (Exception e) {            logger.error("发生了错误:", e);            throw e;        }        //...    }}// 使用,独立写业务

 

性能对比!额,就不去收集对比数据了。第一个自然最快。第二、三个不相伯仲!

封装是为了代码更简洁!哟豁。

 

转载地址:http://xqnno.baihongyu.com/

你可能感兴趣的文章
控制namenode检查点发生的频率
查看>>
Linux存储挂载后,无法正常卸载的解决方法
查看>>
2、递归遍历文件夹下每一个文件
查看>>
Remove auto_increment from Schema Dumps (mysqld...
查看>>
解决activity加上Theme.Translucent.NoTitleBar 页面跳转显示桌面
查看>>
php类库
查看>>
浅谈Java中的对象和引用
查看>>
SQL 注入自我总结
查看>>
Linux线程
查看>>
Exchange Server 2013 系列八:邮箱服务器角色DAG实战
查看>>
一个有趣的命令
查看>>
我的友情链接
查看>>
已发布13集网站开发技术视频:http://blog.sina.com.cn/s/blog_67d27f340102vf7l.html
查看>>
Mysql ibdata 丢失或损坏如何通过frm&ibd 恢复数据
查看>>
MySQL数据库的优化(二)
查看>>
Deepin OS和WIN7双启动 花屏原因一例
查看>>
UIMenuController—为UITextField禁用UIMenuController功能
查看>>
Protobuf使用不当导致的程序内存上涨问题
查看>>
【原创】扯淡的Centos systemd与Docker冲突问题
查看>>
Spring+Mybatis多数据库的配置
查看>>