利用反射实现“风控“功能

文章介绍了如何通过Java反射技术实现动态风控功能,包括规则定义表、业务规则关联、前端管理,以及在流程申报和数据过滤中的应用。核心代码展示了风控方法的实现,强调了反射的效率问题,并提出了异步多线程优化、风控日志记录和业务数据实时更新的策略。
摘要由CSDN通过智能技术生成

利用反射实现“风控“功能



前言

在我们的业务系统中经常会有这样的一种需求,就是需要根据某些规则,对一些实体对象进行过滤,有可能在多个地方都会用到,也不可能在每个地方根据需求来编写重复的内容,所以就有这次根据配置的内容,并且采用Java的反射技术来实现类似“风控”的卡控功能。

反射原理图(来源百度百科):
在这里插入图片描述


一、实现思路

1、首先是一张规则定义表 如图(仅做示例使用)

在这里插入图片描述

2、业务和规则的关联关系 如图(仅做示例使用)

在这里插入图片描述

3、在前端可以实现,对新增的规则进行管理,对某一个具体的业务对象和规则进行关联 如图(仅做示例使用)

在这里插入图片描述

二、应用场景

1、可以在流程申报的时候进行风控

2、需要对数据进行同一个【业务规则】进行过滤

三、大体代码

1、风控核心方法

  /**
    * @param bizName  		业务表名
    * @param bizId    		业务表id
    * @param riskCheckList  统一封装的待风控对象(可自己根据需要修改对象)
    * @param consumer		函数式回调 可自己根据需要调用
    * @return
    */
public ResultMessage checkRuleBatch(String bizName, String bizId, List<RiskCheck> riskCheckList, Consumer<RiskCheck> consumer) {
	 // 根据bizName和bizId查询出所有的启用规则
	 // 循环查询到的规则
     
     rules.forEach(rule -> {
         // 去取方法名称类名以及方法名称
         String ruleMethod = MapUtil.getStr(rule, "rule_method");
         String[] tmp = ruleMethod.split("[.]");
         if (tmp.length != 2) {
             return;
         }
         String beanId = tmp[0];
         String method = tmp[1];
         // 从容器中取得对应的规则bean
         Object serviceBean = AppUtil.getBean(beanId);
         if (serviceBean != null) {
             Method invokeMethod;
             try {
                 // 调用反射取得执行方法
                 invokeMethod = serviceBean.getClass().getDeclaredMethod(method, new Class[]{Map.class});
                 rule.put("invokeMethod", invokeMethod);
                 rule.put("serviceBean", serviceBean);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     });

     // 循环待检查对象 一个对象可能会对应多个规则
     waitCheckList.forEach(riskObjDto -> {
		 // 根据自己的业务需求 处理自己的参数
         rules.forEach(rule -> {
          
             String ruleName = MapUtil.getStr(rule, "rule_name");
             //场景编码       
             Object serviceBean = rule.get("serviceBean");
             Method invokeMethod = (Method) rule.get("invokeMethod");
             if (serviceBean != null && invokeMethod != null) {
                 try {
                     // 统一参数定义  枚举类
                     Map<Common.ParamKey, Object> param = new HashMap<BpmDefinitionRuleManager.ParamKey, Object>();
                     param.put(Common.ParamKey.xxx, 风控参数1);
                     param.put(Common.ParamKey.xxx, 风控参数2);
                     // 调用反射进入规则对应的规则方法  ResultMessage统一结果返回 
                    ResultMessage result =(ResultMessage)invokeMethod.invoke(serviceBean, param);                
                     if (ResultMessage.SUCCESS != result.getResult()) {
						// 成功处理
                     }eles{
                     	// 失败处理
                     }
                     // 记录日志
                     
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
             }
         });
         consumer.accept(riskObjDto);
}

2、规则对应方法(仅示例使用) 需要根据自己的黑名单业务进行修改

/**
 * 黑名单配置拦截
 *
 * @param map 统一参数
 * @return
 * @throws CheckedException
 */
 public ResultMessage checkBlacklist(Map<ParamKey, Object> map) throws CheckedException {
      // 取得参数
      String xxx = MapUtil.getStr(map, ParamKey.xxx);
      // 调用黑名单的业务方法
      int count= checkBlackService.checkBlacklist(xxx);
      if (count> 0) {
          return ResultMessage.getFail("您被记录为黑名单,无法操作!");
      } else {
          return ResultMessage.getSuccess("检查通过!");
      }
  }

3、具体的黑名单检查方法就根据自己系统实现

四、功能优化

1、Java的反射是比较慢的,并且还是对象列表循环,规则循环,两层循环,所以必须要优化执行效率。

优化思路:
采用异步多线程的方法(已实现)
不贴代码了,说一下思路,将待检查的对象列表分组,然后循环调用异步风控核心方法(使用@Async注解要注意,不要写在同一个类,因为它是通过代理实现的)

2、记录风控日志

记录日志 方便后续排查,或者用于数据全景分析(已实现)

3、业务数据的及时更新

在对业务数据有实时性的要求是,可以通过函数式的accpet实现数据的及时更新(已实现)

总结

算是反射的一种用法吧,如有错误,请指正。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值