MyBatisMyBatis之大约通晓Plugin

MyBatis的Configuration配置中有一个Plugin配置,依照其名可以解释为“插件”,这些插件实质可以精通为“拦截器”。“拦截器”那么些名词不面生,在重重框架中均有“拦截器”。这么些Plugin有如何用吧?活着说拦截器有什么用啊?能够考虑拦截器是怎么落实的。Plugin用到了Java中很紧要的一个特征——动态代理。所以这么些Plugin可以知晓为,在调用一个主意时,我“拦截”其方法做一些本人想让它做的事。它可以阻碍以下方法:MyBatis 1

在法定文档中有这么一句话: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。

 1 package day_8_mybatis.util;
 2 
 3 import java.util.Iterator;
 4 import java.util.Map;
 5 import java.util.Properties;
 6 
 7 import org.apache.ibatis.plugin.Interceptor;
 8 import org.apache.ibatis.plugin.Intercepts;
 9 import org.apache.ibatis.plugin.Invocation;
10 import org.apache.ibatis.plugin.Plugin;
11 import org.apache.ibatis.plugin.Signature;
12 
13 /**
14  * @author turbo
15  *
16  * 2016年10月25日
17  */
18 @Intercepts({
19     @Signature(
20         type = Map.class,
21         method = "get",
22         args = {Object.class}
23 )})
24 public class ExamplePlugin implements Interceptor {
25 
26     /* 此方法用于实现拦截逻辑
27      * @see org.apache.ibatis.plugin.Interceptor#intercept(org.apache.ibatis.plugin.Invocation)
28      */
29     @Override
30     public Object intercept(Invocation invocation) throws Throwable {
31         
32         return "ExamplePlugin";
33     }
34 
35     /* 使用当前的这个拦截器实现对目标对象的代理(内部实现时Java的动态代理)
36      * @see org.apache.ibatis.plugin.Interceptor#plugin(java.lang.Object)
37      */
38     @Override
39     public Object plugin(Object target) {
40         return Plugin.wrap(target, this);
41     }
42 
43     /* 此方法和上一节所讲的自定义对象工厂中的setProperties一样,初始化Configuration时通过配置文件配置property传递参数给此方法并调用。
44      * @see org.apache.ibatis.plugin.Interceptor#setProperties(java.util.Properties)
45      */
46     @Override
47     public void setProperties(Properties properties) {  
48         Iterator iterator = properties.keySet().iterator();
49         while (iterator.hasNext()){
50             String keyValue = String.valueOf(iterator.next());
51             System.out.println(properties.getProperty(keyValue));
52         }
53     }
54 
55 }

别忘了在mybatis-config.xml的布局文件中注册自定义Plugin。(下边的布署中有一部分残存代码,是在上两节中的配置,可以接纳性的忽视。)

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE configuration  
 3   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
 4   "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5   
 6 <configuration>
 7 <!-- 注意configuration中各个属性配置的顺序应为:properties,settings,typeAliases,typeHandlers,objectFactory,objectWrapperFactory,reflectorFactory,plugins,environments,databaseIdProvider,mappers)-->
 8     <properties>
 9         <property name="driver" value="com.mysql.jdbc.Driver"/>
10         <property name="url" value="jdbc:mysql://localhost:3306/test"/>    
11         <property name="username" value="root"/>
12         <property name="password" value="0000"/>
13     </properties>
14     <!-- 
15     <typeHandlers>
16         <typeHandler handler="day_8_mybatis.util.ExampleTypeHandler" javaType="java.util.Date" jdbcType="VARCHAR"/>
17     </typeHandlers>
18     <objectFactory type="day_8_mybatis.util.ExampleObjectFactory">
19         <property name="someProperty" value="100"/>
20     </objectFactory>
21      -->
22     <plugins>
23         <plugin interceptor="day_8_mybatis.util.ExamplePlugin">
24             <property name="someProperty" value="100"/>
25         </plugin>
26     </plugins>
27     <environments default="development">
28         <environment id="development">
29             <transactionManager type="JDBC" />
30             <dataSource type="POOLED">
31                 <property name="driver" value="${driver}"/>
32                 <property name="url" value="${url}"/>
33                 <property name="username" value="${username}"/>
34                 <property name="password" value="${password}"/>
35             </dataSource>            
36         </environment>
37     </environments> 
38     <mappers>
39         <mapper resource="day_8_mybatis/mapper/UserMapper.xml"/>
40         <mapper resource="day_8_mybatis/mapper/NoteMapper.xml"/>
41     </mappers>    
42     
43 </configuration>
44 
45  

客户端测试代码:

 1 package day_8_mybatis;
 2 
 3 import java.io.IOException;
 4 import java.util.HashMap;
 5 import java.util.Map;
 6 
 7 import org.apache.ibatis.session.SqlSession;
 8 
 9 import day_8_mybatis.util.ExamplePlugin;
10 import day_8_mybatis.util.SessionFactory;
11 
12 /**
13  * 客户端
14  * @author turbo
15  *
16  * 2016年10月25日
17  */
18 public class Main {
19 
20     /**
21      * @param args
22      * @throws IOException 
23      */
24     public static void main(String[] args) throws Exception {
25         String resource = "day_8_mybatis/mybatis-config.xml";        //获取mybatis配置文件路径
26         SqlSession sqlSession = SessionFactory.getSqlSession(resource);    //通过SessionFactory工具类(此工具类为自己构造即util包中的SessionFactory)构造SqlSession
27         
28         Map map = new HashMap();
29         map = (Map)new ExamplePlugin().plugin(map);
30         System.out.println(map.get(""));
31 
32     }
33 
34 }

于今,我们就概括的询问了MyBatis中的Plugin。有趣味的能够看看大家在客户端测试代码中的第29行所调用的plugin方法。即调用了Plugin类的静态方法wrap(Object
target, Interceptor
intercpetor),追踪该方法会发现,此办法即是Java的动态代理。

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

动态代理很要紧,反射很要紧。一定要频繁精通精晓动态代理以及反射,那对我们读懂很多框架源代码有很大扶持。那篇只有简单询问,不做过多的记忆犹新。

 

网站地图xml地图