MyBatis拦截器Inteceptor

本文详细介绍了MyBatis插件机制的实现原理,包括其如何利用Java动态代理实现责任链模式,以及如何通过自定义拦截器实现对特定方法的拦截。


转载自JavaTalk – zhouhaocheng.com


MyBatis的插件机制,实际就是Java动态代理实现的责任链模式实现。

根据官方文档。Mybatis只允许拦截以下方法,这个决定写拦截器注解签名参数。

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

拦截处理的源码如下,其中interceptorChain.pluginAll(..)即为织入自定义拦截器:

/* org.apache.ibatis.session.Configuration类中方法 */
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
   ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
   /* 拦截ParameterHandler*/
   parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
   return parameterHandler;
}

public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,
      ResultHandler resultHandler, BoundSql boundSql) {
   ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
   /* 拦截ResultSetHandler*/
   resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
   return resultSetHandler;
}

public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
   StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
     /* 拦截StatementHandler*/
   statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
   return statementHandler;
}

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
  executorType = executorType == null ? defaultExecutorType : executorType;
  executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
  Executor executor;
  if (ExecutorType.BATCH == executorType) {
    executor = new BatchExecutor(this, transaction);
  } else if (ExecutorType.REUSE == executorType) {
    executor = new ReuseExecutor(this, transaction);
  } else {
    executor = new SimpleExecutor(this, transaction);
  }
  if (cacheEnabled) {
    executor = new CachingExecutor(executor);
  }
   /* 拦截Executor*/
  executor = (Executor) interceptorChain.pluginAll(executor);
  return executor;
}

实现一个自定义拦截器只需实现Interceptor接口即可,大致代码如下:

/* 注解表明要拦截哪个接口的方法及其参数 */
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class YourInterceptor implements Interceptor{

  public Object intercept(Invocation invocation) throws Throwable{
    doSomeThing();
    /* 注:此处实际上使用Invocation.proceed()方法完成interceptorChain链的遍历调用(即执行所有注册的Interceptor的intercept方法),到最终被代理对象的原始方法调用 */
    return invocation.proceed();
  }

   /*生成成对目标target的代理,而@Intercepts的注解是在Plugin.wrap中用到*/
  @Override
  public Object plugin(Object target){
     /* 当目标类是StatementHandler类型时,才包装目标类,不做无意义的代理 */
    return (target instanceof StatementHandler)?Plugin.wrap(target, this):target;
  }

   /*用于设置自定义的拦截器配置参数*/
  @Override
  public void setProperties(Properties properties){
  }
}

其中,拦截调用的代码均在Plugin.wrap中:

/* org.apache.ibatis.plugin.Plugin类 */
public class Plugin implements InvocationHandler {

  /* 省略代码... */

  public static Object wrap(Object target, Interceptor interceptor) {
    /* 此处即为获取Interceptor的注解签名 */
    Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
    Class<?> type = target.getClass();
    /* 获取拦截目标类相匹配的接口 */
    Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
    if (interfaces.length > 0) {
      /* 使用jdk动态代理 */
      return Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap));
    }
    return target;
  }

  /* 拦截目标类的所有方法的执行都会变为在此执行 */
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      Set<Method> methods = signatureMap.get(method.getDeclaringClass());
      if (methods != null && methods.contains(method)) {
        /* 执行拦截器方法 */
        return interceptor.intercept(new Invocation(target, method, args));
      }
      return method.invoke(target, args);
    } catch (Exception e) {
      throw ExceptionUtil.unwrapThrowable(e);
    }
  }

  /* 省略代码... */

}


这个是完整源码 python实现 大数据 Spark pyspark 可视化大屏+Kafka+FastAPI+Vue3 【深度学习毕业设计】人脸识别 智能门禁系统(深度学习+OpenCV DNN+FastAPI+Vue3) 源码+论文 完整版 数据库Mysql 出入控制是安防体系中的基础环节。长期以来,IC 卡、密码键盘和门禁钥匙在企事业单位中广泛使用,但存在卡片易丢失、密码易泄露、冒用难追溯等问题。尤其在人员流动性较高的园区与写字楼场景中,卡片补办成本高,权限变更往往滞后,管理方难以及时掌握“谁在何时从何处进出”的完整信息。近年来,深度学习推动生物特征识别技术快速落地,人脸识别因采集成本低、通行体验好、可与视频监控联动,成为智能门禁的主流方案之一。 在智慧园区和数字化办公场景中,门禁系统不仅要完成“开门”,还要完成“管人、管设备、管权限、管记录、管告警”的闭环。将人脸识别与后台管理系统结合,能够把身份核验、权限策略和安全事件处理统一到同一平台,提升管理效率与安全水平。对组织管理者而言,系统可以支撑考勤辅助、访客管控与安全审计;对通行者而言,非接触式识别减少了掏卡刷卡的繁琐步骤,也降低了交叉接触风险。因此,研究并实现一套结构清晰、技术路线明确、可演示可扩展的带人脸识别智能门禁系统,具有明确的工程意义与教学价值。 本课题选择 OpenCV DNN、YuNet 与 SFace 作为识别技术路线,结合 Python、FastAPI 与 Vue3 完成系统开发。该方案无需依赖商业闭源 SDK,模型文件体积较小,部署门槛低,适合本科毕业设计在有限硬件条件下完成可运行原型,同时又能体现深度学习在实际工程中的应用方式。与单纯调用云端识别 API 相比,本地化推理更有利于保护人脸生物特征数据,也便于在论文中完整展示算法调用链路与系统设计细节。 从人才培养角度看,本课题横跨软件工程、数据库原
内容概要:本文针对微电网在遭受间歇性拒绝服务(DoS)攻击下的运行安全问题,提出了一种融合混合动态事件触发机制的多目标二次均衡控制策略。该方法通过设计弹性控制架构与动态事件触发机制,在有效抵御间歇性DoS阻断攻击的同时,降低系统通信负担,保障控制信号的可靠传输。所提策略实现了频率与电压的协同调节,兼顾系统稳定性与控制精度,并在存在网络攻击扰动的情况下仍能维持良好的动态响应性能。通过Simulink平台构建微电网仿真模型,验证了该控制方案在多种攻击场景下的有效性与鲁棒性,为提升网络物理系统在恶意攻击下的安全运行能力提供了可行的技术路径。; 适合人群:具备电力系统自动化、控制理论或网络安全基础知识,从事微电网、智能配电网、分布式能源系统等领域研究的硕士/博士研究生、高校科研人员及电力行业工程技术开发者。; 使用场景及目标:①提升微电网在面临网络攻击时的运行韧性与安全性;②优化受限通信资源下的控制效率与实时性;③实现多目标二次控制与攻击容忍机制的协同设计;④为高可靠性能源互联网系统的仿真建模与防御策略验证提供技术支持。; 阅读建议:建议结合提供的Simulink仿真模型深入理解控制结构与事件触发条件的设计逻辑,重点关注系统在不同时序攻击模式下的状态响应变化,并可通过修改攻击强度、触发阈值等参数进行对比实验,进一步拓展至其他网络化控制系统中的安全控制研究。
内容概要:本文围绕光伏阵列非线性输出耦合储能电池的独立直流供电系统,开展能量均衡建模与分层控制策略研究,重点探讨离网光伏直流微网中功率供需失衡的抑制机制。通过Simulink搭建包含PV光伏阵列、Boost DC-DC变换器、双向DC-DC变换器与锂离子电池的系统仿真模型,结合最大功率点跟踪(MPPT)技术和储能系统的双向充放电控制,实现光伏能量的高效捕获与储能系统的削峰填谷协同调控,进而提升系统能量利用效率与供电稳定性。研究涵盖多模块耦合建模、双级电力电子协同调控、分层控制架构设计等内容,并辅以模型预测控制(MPC)、虚拟同步机(VSG)等先进控制策略,增强系统在扰动和间歇性出力下的动态响应能力与鲁棒性。; 适合人群:具备电力电子、新能源系统或自动控制相关背景,从事光伏储能系统、微电网、智能控制等领域研究的科研人员及工程技术人员,尤其适合研究生及以上层次的研究者。; 使用场景及目标:① 构建离网光伏储能直流系统的完整Simulink仿真模型;② 实现MPPT与储能双向充放电的协同控制策略设计;③ 研究系统在光照波动、负载变化等扰动条件下的能量均衡与稳定运行机制;④ 掌握分层控制、模型预测控制等先进控制方法在新能源系统中的应用; 阅读建议:建议结合文中提及的Simulink仿真资源与MATLAB代码实践操作,逐步复现模型并调试控制参数,重点关注系统动态响应、能量流动平衡与控制策略有效性,同时参考团队提供的网盘资料与公众号资源获取完整代码与案例支持。
覆盖了不同佩戴姿势、光Y照O条L件O和v背1景1干扰室下内的办手公套环实境例绝,缘为手开套发目精标准检的测手数部据防集 护装目备标检类测别模:[型'提L供了e可f靠t的 数I据n基s础u。 l从a数t据i分o布n来 看G,l该o数v据e集s合'理,划 分'了R训i练g集h(1t5 9I3ns张u)l、a验t证i集o(4n5 5Gl张o)v和e测s试'集](2 2中8文类张别):,[比'例约左为侧7绝:缘2手:套'1,, 确'保了右模侧型绝训缘练手、套'调]优 和评训估练的集完:1整5流9程3。 各子张 集在验手证套集类:4型5、5佩 戴方张 式和测背试景集特:2征上2具8有 良好张 的分总布计一:2致2性7,6能 够有张 效支该持数模据型集的提泛供化了d能a力t验a证.。 ya在m标l注质文量件方,面内,容该如数下据:集 展t现r了a极i高n的:专 业.水.准/。t所r有a图i像n均/采i用m精a确g的e矩s形 框v标a注l,:边 界.框.严/格v贴a合l手i套d轮/廓i,m且a标g注e者s对 左t右e手s区t分:清 晰.准.确/。标t注e过s程t遵/循i统m一a规g范e,s确 保n了c数:据 的2一 致n性a和m可e靠s性:, 为[后'续L模e型f训t练 奠I定n了s坚u实l基a础t。 io该n数据 集G可l广o泛v应e用s于'电,力 维'修R、i工g业h操t作 等I需n要s手u部l防a护t的i场o景n, 特G别l是o在v电e气s设'备]检 修Y、O高L压O作v业1等1专业室领内域办。公其环高境精绝度缘的手检套测目能标力检有测助数于据提集 升作该业数安据全集性专,注辅于助室智内能办穿公戴场设景备中开绝发缘,手并套为的工目业标安检全测监任控务系,统通提过供系可统靠化的的技图术像支采撑集。与标注,构建了高质量的训练样本。数据集包含2276张图像,覆盖了不同佩戴姿势、光照条件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值