zoukankan      html  css  js  c++  java
  • 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>
    


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

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




  • 相关阅读:
    C和指针学习笔记--第五章
    C和指针学习笔记--第四章
    C和指针学习笔记--第三章
    ipables常用命令
    linux网络设计与实现-----第一章
    iptables
    cJSON学习
    Makefile-更新函数库文件
    Makefile隐晦规则
    【Spark学习笔记】01-Spark简介
  • 原文地址:https://www.cnblogs.com/huangzhe1515023110/p/9276077.html
Copyright © 2011-2022 走看看