本文中的源代码分析基于Mybatis 3.5.8版本。
首先,应该解释说,本文不是Mybatis插头开发的教程,而是Mybatis如何从源代码级别支持用户定义的插件开发。
Mybatis的插头机制大大提高了其扩展功能。例如,它经常在我们的项目中使用。这是一种基于Mybatis插头功能开发的产品。它的功能是使基于Mybatis的数据库分页查询更易于使用。
当然,我们还可以根据插件开发其他功能,例如在执行SQL,权限控制等之前打印日志等。
Mybatis插头 - 也称为Mybatis Interceptor,它支持从方法级别拦截Mybatis。总体体系结构图如下:
解释接下来的几个相关概念:
mybatis的支持在哪里?您只需要在代码中的代码中搜索以获取答案,到处都有很多:
这四个原则是相同的,我们只需要选择一个来分析即可。
首先,让我们看一下如何加载自定义插件。例如,当我们使用插头-in时,我们通常添加以下配置:
Mybatis创建时会加载配置文件,
parseconfigution方法将加载许多配置,包括插件和
插件做了几件事:
Mybatis的插头 - 通过动态代理实现。然后,它必须生成代理对象。生成的逻辑是前面提到的方法。例如,对于代理对象,
然后查看插件方法,
它遍历了我们定义的所有拦截器,并调用拦截器的插件方法生成代理对象。有些人可能有疑问:如果有多个拦截器,是否涵盖了目标?
实际上,如果有多个拦截器,则生成的代理对象将由另一个代理对象表示以形成代理链。执行时,依次执行所有拦截器的拦截逻辑代码。
该方法是接口的默认实现类,
然后输入,
首先是获取由我们自己的实现实现的拦截器的签名映射表。是使用代理类创建新的二氧化碳的最关键步骤。
请注意,NewProxyinstance方法的第三个参数是由IncocationHandler对象接收的,这意味着当将Dynamic代理对象调用方法关联时,InvocationHandler对象将关联哪些,并最终被调用。
我们在插件类中传递此处,因此插件的调用方法将在动态操作期间执行。
如果您不了解本段,建议首先了解Java Dynamic代理的原理。在Java Dynamic Agency机制中有两个重要角色:InvocationHandler(接口)和代理(类),这就是背景知识需要掌握。
我们深入查看上述方法,
首先,您需要从Internet类获得拦截注释,这表明我们的自定义拦截器需要注释。例如,PageHelper插件的定义如下:
因此,我们可以知道GetSignatureMap实际上正在获得与我们自定义拦截器声明的拦截相对应的类和类。
如前所述,当我们调用代理对象时,插件类的调用方法最终将执行。
拦截器接口的Internet方法是我们自定义需要实现的拦截器的逻辑。参数是调用。您可以从invocation参数.pecial逻辑中获取对象,方法和方法参数。
在此方法的末尾,您需要调用Invocation#groump()方法以传播拦截器链。
参考: