核心对象
MyBatis 插件的运行是基于 JDK 动态代理 + 拦截器链实现
-
Interceptor 是拦截器,可以拦截 Executor, StatementHandle, ResultSetHandler, ParameterHandler 四个接口
实际就是利用 JDK动态代理,生成对应的代理类实例,通过
InvocationHandler#invoke
实现拦截逻辑 -
InterceptorChain 是拦截器链,对象定义在 Configuration 类中, 实际是一个 List集合,元素就是 Interceptor接口的实现类
-
Invocation 是对方法、方法参数、执行对象和方法的执行的封装,就是对
InvocationHandler#invoke
方法参数的封装
加载解析拦截器
mybatis-config.xml
<configuration>
<plugins>
<plugin interceptor="io.github.tangmonkmeat.MyInterceptor1" />
<plugin interceptor="io.github.tangmonkmeat.MyInterceptor2"/>
</plugins>
</configuration>
拦截器的解析是在 XMLConfigBuilder
对象的 parseConfiguration
方法中,
如果是 Mybatis ,则从 SqlSessionFactoryBuilder#build
方法开始
如果是 springboot-mybatis-starter,则从 SqlSessionFactoryBean#buildSqlSessionFactory
开始
private void parseConfiguration(XNode root) {
try {
// issue #117 read properties first
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
loadCustomLogImpl(settings);
typeAliasesElement(root.evalNode("typeAliases"));
// 开始加载解析插件的标签,添加到 Configuration
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
environmentsElement(root.evalNode("environments"));
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
typeHandlerElement(root.evalNode("typeHandlers"));
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " &