mybatis插件机制

  作者:记性不好的阁主

插件执行流程




例子:


package com.laoxu.mybatis.executor.plugin;

import org.apache.ibatis.plugin.*;

import java.util.Properties;

public class Test2 {

public static void main(String[] args) {
test1();
}

private static void test1(){
MyPlugin myPlugin = new MyPlugin() {
@Override
public String sayHi(String name) {
System.out.println("hello " + name);
return "hello " + name;
}
};
Interceptor interceptor = null;
MyPlugin wrap = (MyPlugin) Plugin.wrap(myPlugin, new MyInterceptor());
wrap.sayHi("程序员");
}

public interface MyPlugin{
String sayHi(String name);
}

@Intercepts(
@Signature(
type = MyPlugin.class,
method = "sayHi",
args = {String.class}
))
public static class MyInterceptor implements Interceptor {

@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("你好");
return invocation.proceed();
}

@Override
public Object plugin(Object target) {
return null;
}

@Override
public void setProperties(Properties properties) {

}
}

}


执行结果:


你好
hello 程序员


1、根据注解获取 Map<Class<?>, Set<Method>> 这么一个多个类的多个方法map




{
    "com.laoxu.mybatis.executor.plugin.Test2$MyPlugin": [
        {
            "accessible"false,
            "annotatedExceptionTypes": [],
            "annotatedParameterTypes": [
                {
                    "annotations": [],
                    "declaredAnnotations": [],
                    "type""java.lang.String"
                }
            ],
            "annotatedReceiverType": {
                "annotations": [],
                "declaredAnnotations": [],
                "type""com.laoxu.mybatis.executor.plugin.Test2$MyPlugin"
            },
            "annotatedReturnType": {
                "annotations": [],
                "declaredAnnotations": [],
                "type""java.lang.String"
            },
            "annotations": [],
            "bridge"false,
            "declaringClass""com.laoxu.mybatis.executor.plugin.Test2$MyPlugin",
            "default"false,
            "exceptionTypes": [],
            "genericExceptionTypes": [],
            "genericParameterTypes": [
                "java.lang.String"
            ],
            "genericReturnType""java.lang.String",
            "modifiers"1025,
            "name""sayHi",
            "parameterAnnotations": [
                []
            ],
            "parameterCount"1,
            "parameterTypes": [
                "java.lang.String"
            ],
            "returnType""java.lang.String",
            "synthetic"false,
            "typeParameters": [],
            "varArgs"false
        }
    ]
}


2、获取传入的目标类




3、获取该目标类下的所有接口




也就是此例的sayHi接口




4、动态代理执行插件的sayHi方法




调用invoke方法




获取方法集合




[
    {
        "accessible"false,
        "annotatedExceptionTypes": [],
        "annotatedParameterTypes": [
            {
                "annotations": [],
                "declaredAnnotations": [],
                "type""java.lang.String"
            }
        ],
        "annotatedReceiverType": {
            "annotations": [],
            "declaredAnnotations": [],
            "type""com.laoxu.mybatis.executor.plugin.Test2$MyPlugin"
        },
        "annotatedReturnType": {
            "annotations": [],
            "declaredAnnotations": [],
            "type""java.lang.String"
        },
        "annotations": [],
        "bridge"false,
        "declaringClass""com.laoxu.mybatis.executor.plugin.Test2$MyPlugin",
        "default"false,
        "exceptionTypes": [],
        "genericExceptionTypes": [],
        "genericParameterTypes": [
            "java.lang.String"
        ],
        "genericReturnType""java.lang.String",
        "modifiers"1025,
        "name""sayHi",
        "parameterAnnotations": [
            []
        ],
        "parameterCount"1,
        "parameterTypes": [
            "java.lang.String"
        ],
        "returnType""java.lang.String",
        "synthetic"false,
        "typeParameters": [],
        "varArgs"false
    }
]


调用目标插件实现的intercept方法




/**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.plugin;

import java.util.Properties;

/**
* @author Clinton Begin
*/
public interface Interceptor {

Object intercept(Invocation invocation) throws Throwable;

default Object plugin(Object target) {
return Plugin.wrap(target, this);
}

default void setProperties(Properties properties) {
// NOP
}

}




最终调用了sayHi方法





总结:插件实现机制为动态代理


相关推荐

评论 抢沙发

表情

分类选择