MyBatis的Configuration配置中有一个Plugin配置,根据其名可以解释为“插件”,这个插件实质可以理解为“拦截器”。“拦截器”这个名词不陌生,在众多框架中均有“拦截器”。这个Plugin有什么用呢?活着说拦截器有什么用呢?可以想想拦截器是怎么实现的。Plugin用到了Java中很重要的一个特性——动态代理。所以这个Plugin可以理解为,在调用一个方法时,我“拦截”其方法做一些我想让它做的事。它可以拦截以下方法:

在官方文档中有这么一句话:If you attempt to modify or override the behaviour of a given method, you’re likely to break the core of MyBatis. 谨慎使用自定义Plugin拦截器,因为它可能修改Mybatis核心的东西。实现自定义Plugin我们需要实现 Interceptor接口。并未这个类注解@Intercepts。

 package day_8_mybatis.util;

 import java.util.Iterator;
import java.util.Map;
import java.util.Properties; import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature; /**
* @author turbo
*
* 2016年10月25日
*/
@Intercepts({
@Signature(
type = Map.class,
method = "get",
args = {Object.class}
)})
public class ExamplePlugin implements Interceptor { /* 此方法用于实现拦截逻辑
* @see org.apache.ibatis.plugin.Interceptor#intercept(org.apache.ibatis.plugin.Invocation)
*/
@Override
public Object intercept(Invocation invocation) throws Throwable { return "ExamplePlugin";
} /* 使用当前的这个拦截器实现对目标对象的代理(内部实现时Java的动态代理)
* @see org.apache.ibatis.plugin.Interceptor#plugin(java.lang.Object)
*/
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
} /* 此方法和上一节所讲的自定义对象工厂中的setProperties一样,初始化Configuration时通过配置文件配置property传递参数给此方法并调用。
* @see org.apache.ibatis.plugin.Interceptor#setProperties(java.util.Properties)
*/
@Override
public void setProperties(Properties properties) {  
Iterator iterator = properties.keySet().iterator();
while (iterator.hasNext()){
String keyValue = String.valueOf(iterator.next());
System.out.println(properties.getProperty(keyValue));
}
} }

别忘了在mybatis-config.xml的配置文件中注册自定义Plugin。(下面的配置中有一些遗留代码,是在上两节中的配置,可以选择性的忽略。)

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration>
<!-- 注意configuration中各个属性配置的顺序应为:properties,settings,typeAliases,typeHandlers,objectFactory,objectWrapperFactory,reflectorFactory,plugins,environments,databaseIdProvider,mappers)-->
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="0000"/>
</properties>
<!--
<typeHandlers>
<typeHandler handler="day_8_mybatis.util.ExampleTypeHandler" javaType="java.util.Date" jdbcType="VARCHAR"/>
</typeHandlers>
<objectFactory type="day_8_mybatis.util.ExampleObjectFactory">
<property name="someProperty" value="100"/>
</objectFactory>
-->
<plugins>
<plugin interceptor="day_8_mybatis.util.ExamplePlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="day_8_mybatis/mapper/UserMapper.xml"/>
<mapper resource="day_8_mybatis/mapper/NoteMapper.xml"/>
</mappers> </configuration>

客户端测试代码:

 package day_8_mybatis;

 import java.io.IOException;
import java.util.HashMap;
import java.util.Map; import org.apache.ibatis.session.SqlSession; import day_8_mybatis.util.ExamplePlugin;
import day_8_mybatis.util.SessionFactory; /**
* 客户端
* @author turbo
*
* 2016年10月25日
*/
public class Main { /**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws Exception {
String resource = "day_8_mybatis/mybatis-config.xml"; //获取mybatis配置文件路径
SqlSession sqlSession = SessionFactory.getSqlSession(resource); //通过SessionFactory工具类(此工具类为自己构造即util包中的SessionFactory)构造SqlSession Map map = new HashMap();
map = (Map)new ExamplePlugin().plugin(map);
System.out.println(map.get("")); } }

至此,我们就简单的了解了MyBatis中的Plugin。有兴趣的可以看看我们在客户端测试代码中的第29行所调用的plugin方法。即调用了Plugin类的静态方法wrap(Object target, Interceptor intercpetor),追踪该方法会发现,此方法即是Java的动态代理。

 public static Object wrap(Object target, Interceptor interceptor)
{
Map signatureMap = getSignatureMap(interceptor);
Class type = target.getClass();
Class interfaces[] = getAllInterfaces(type, signatureMap);
if(interfaces.length > 0)
return Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap));  //返回代理类实例
else
return target;
}

动态代理很重要,反射很重要。一定要反复理解领会动态代理以及反射,这对我们读懂很多框架源代码有很大帮助。这篇仅仅简单了解,不做过多的深入。

MyBatis之简单了解Plugin的更多相关文章

  1. 简单webpack plugin 开发

    重要是学习下怎么开发webpack plugin,同时记录下 插件模型 webpack 是一个插件,可以是javascript class ,或者具名 class 定义apply 方法 指定一个绑定到 ...

  2. Mybatis框架简单使用

    Mybatis框架简单使用 环境搭建 新建一个JavaWeb项目,在web\WEB-INF\创建lib文件,并且在其下添加Mybatis的核心包以及依赖包,以及Mysql驱动包,junit4测试包等. ...

  3. MyBatis(1)-简单入门

    简介 什么是 MyBatis ? MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.My ...

  4. MyBatis 使用简单的 XML或注解用于配置和原始映射

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .My ...

  5. 单独使用MyBatis的简单示例

    单独使用MyBatis的简单示例:mybaties-config.xml:MyBatis配置文件 <?xml version="1.0" encoding="UTF ...

  6. Mybatis的简单增删改查

    刚开始学习Mybatis可以先看下官方文档,MyBatis是支持定制化SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis避免了几乎所有的JDBC代码和手工设置参数以及抽取结果集.MyBat ...

  7. Mybatis实现简单的CRUD(增删改查)原理及实例分析

    Mybatis实现简单的CRUD(增删改查) 用到的数据库: CREATE DATABASE `mybatis`; USE `mybatis`; DROP TABLE IF EXISTS `user` ...

  8. Mybatis实现简单增删改查

    Mybatis的简单应用 学习内容: 需求 环境准备 代码 总结: 学习内容: 需求 使用Mybatis实现简单增删改查(以下是在IDEA中实现的,其他开发工具中,代码一样) jar 包下载:http ...

  9. Maven+Mybatis一些简单例子

    一.创建maven工程 把依赖的包写在pom.xml中.保存后,工程会有错,需要在工程上右键选择“Maven-->Update Project” pom.xml内容为 <project x ...

随机推荐

  1. 从以往子类化跟踪MouseLeave深入讨论VB6的自定义Hook类

    一.关于起因 之前发过一篇博文,是关于VB6中跟踪鼠标移出事件的示例(http://www.cnblogs.com/alexywt/p/5891827.html) 随着业务状况的不断发展,提出了更多的 ...

  2. 回答: 2017-03-19的关于css+div布局的疑问 2017-04-05

    原问题为红色,回答为黑色 第一次布局一个静态网页,发现许多细节都需要自己探索,出现诸如以下问题: 1.布局问题:经常出现一个div被挤出来?做到一半少一个div布局? 布局之前,要点打好框架,明确每个 ...

  3. 翻译一篇文章:It's Difficult to Grow a Test Developer(成为测试开发工程师的艰辛)

    翻译一篇文章:It's Difficult to Grow a Test Developer(成为测试开发工程师的艰辛)   以下文章是送给来poptest学习测试开发工程师的学员们,很多人想测试工程 ...

  4. [编织消息框架][JAVA核心技术]动态代理应用4

    基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...

  5. java基础之类与对象3

    前面我的两篇文章主要介绍了将怎么将事物抽象为对象,以及对象的实例化(就是new一个对象).这篇文章里面我就讲下匿名对象... 还是就举之前的例子把,Car c = new Car();看到这个我们就知 ...

  6. firefox上安装selenium ide失败

    Selenium 初学者第一步: 最近在学习selenium,但是在安装的时候遇到了问题.我是直接在firefox安装的Selenium IDE ,虽然下载安装之后存在于扩展中,但是工具栏里并没有显示 ...

  7. Java虚拟机创建对象的内存分配以及对象的内存布局

    本博文知识参考周志明<深入理解Java虚拟机> Java虚拟机在创建对象使如果进行内存分配: 1.指针碰撞 2.空闲列表 Java在多线程情况下创建对象的内存分配: Java完成对象内存分 ...

  8. jquery控制图片切换

    这种js现在用的很多.同时网上的js代码页很多.我直接从网上当了一个来用:代码如下: html <div class="bannerbox">              ...

  9. Object类型知识总结,你掌握了多少?

      Object类型    ECMAScript中的对象其实就是一组数据和功能的集合.对象可以通过执行new操作符后跟要创建的对象类型的名称来创建.而创建Object类型的实例并为其添加属性和(或)方 ...

  10. GitHub上最受欢迎的iOS开源项目TOP20

    AFNetworking 在众多iOS开源项目中,AFNetworking可以称得上是最受开发者欢迎的库项目.AFNetworking是一个轻量级的iOS.Mac OS X网络通信类库,现在是GitH ...