• Mybatis插件原理


     插件原理

         * 在四大对象创建的时候
         * 1、每个创建出来的对象不是直接返回的,而是
         *      interceptorChain.pluginAll( parameterHandler )
         *
         * 2、获取到所有的interceptor(基于拦截器原理)(插件需要实现的接口)
         *      调用所有的Interceptor.pluginAll(target);返回target包装后的对象
         * 3、插件机制,我们可以使用插件为目标对象创建一个代理对象:AOP(面向切面的方式)
         *      我们的插件可以为四大对象创建出代理对象
         *      代理对象就可以拦截到四大对象的每一个执行方法

    public Object pluginAll(Object target){
        for (Interceptor interceptor:interceptors) {
            target = interceptor.plugin(target);
        }
        return target;
    }

    插件编写:

    1、编写Interceptor的实现类

    2、使用@Intercepts注解完成插件签名

    /**
     * 完成了插件签名:告诉mybatis当前插件用来拦截哪个对象的哪个方法
     */
    @Intercepts({
            @Signature(type = StatementHandler.class,method = "parameterize",args = java.sql.Statement.class)
    })
    public class MyFirstPlugin implements Interceptor {
        /**
         * intercept:拦截
         *      拦截目标对象的方法的执行
         * @param invocation
         * @return
         * @throws Throwable
         */
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            System.out.println("MyFirstPlugin....interceptor:"+invocation.getMethod());
            //执行目标方法
            Object proceed = invocation.proceed();
            //返回执行后的返回值
            return proceed;
        }
    
        /**
         * plugin:包装目标对象——包装:为目标对象创建一个代理类
         * @param target
         * @return
         */
        @Override
        public Object plugin(Object target) {
            System.out.println("MyFirstPlugin....plugin:mybatis将要包装的对象"+target);
            //我们可以借助Plugin的wrap方法来使用当前的intercept包装我们目标对象
            Object wrap = Plugin.wrap(target, this);
            //返回为当前target创建好的动态代理
            return wrap;
        }
    
        /**
         * setProperties:将插件注册时的property属性设置进来
         * @param properties
         */
        @Override
        public void setProperties(Properties properties) {
            System.out.println("插件配置的信息"+properties);
        }
    }


    3、将写好的插件注册到全局配置文件中

    <!--
    注册插件
    interceptor:插件的全类名
    -->
    <plugins>
        <plugin interceptor="dao.MyFirstPlugin">
            <!--一下属性会被插件的属性包装-->
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </plugin>
    </plugins>

    运行结果:



    多个插件运行原理

    @Intercepts(
         {
            @Signature(type = StatementHandler.class,method = "parameterize",args = java.sql.Statement.class)
         }
    )
    public class MySecondPlugin implements Interceptor {
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            System.out.println("MySecondPlugin.....interceptor"+invocation.getMethod());
            Object proceed = invocation.proceed();
            return proceed;
        }
    
        @Override
        public Object plugin(Object o) {
            System.out.println("MySecondPlugin.....plugin"+o);
            return Plugin.wrap(o,this);
        }
    
        @Override
        public void setProperties(Properties properties) {
    
        }
    }
    
    <plugins>
        <plugin interceptor="dao.MyFirstPlugin">
            <!--一下属性会被插件的属性包装-->
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </plugin>
        <plugin interceptor="dao.MySecondPlugin"></plugin>
    </plugins>
    


    多个插件就会产生多层代理

    创建动态代理的时候是按照插件配置顺序创建层层动态代理对象,执行目标方法的时候是按照逆序来的




  • 相关阅读:
    leetcode33. Search in Rotated Sorted Array
    pycharm 设置sublime text3 monokai主题
    django class Meta
    leetcode30, Substring With Concatenation Of All Words
    Sublime text3修改tab键为缩进为四个空格,
    sublime text3 python打开图像的问题
    安装上imesupport输入法依然不跟随的解决办法,
    sublime text3 的插件冲突弃用问题,
    sublime text3 BracketHighlighter括号匹配的设置
    windows 下wget的使用
  • 原文地址:https://www.cnblogs.com/huangzhe1515023110/p/9276077.html
Copyright © 2020-2023  润新知