mybatis-插件开发

  在Executor、StatementHandler、parameterHandler、resultSetHandler创建的时候都有一步这样的操作xxxHandler=interceptorChain.pluginAll(xxxHandler);而这个方法会获取到所有的Interceptor(拦截器),调用interceptor.plugin(target),返回target包装后的对象

插件实现

编写Interceptor的实现类,使用@Intercepts拦截对象的方法

@Intercepts(
        {
            @Signature(type=StatementHandler.class,method="parameterize",args=java.sql.Statement.class)
        })
public class MyFirstPlugin implements Interceptor{

    /**
     *  拦截目标对象的目标方法的执行
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("MyFirstPlugin...intercept:"+invocation.getMethod());
        Object target = invocation.getTarget();
        System.out.println("当前拦截到的对象:"+target);//拿到target的元数据
        MetaObject metaObject = SystemMetaObject.forObject(target);
        Object value = metaObject.getValue("parameterHandler.parameterObject");
        System.out.println("sql语句用的参数是:"+value);
        //修改完sql语句要用的参数
        metaObject.setValue("parameterHandler.parameterObject", 11);
        //执行目标方法
        Object proceed = invocation.proceed();
        //返回执行后的返回值
        return proceed;
    }

    /**
     *  包装目标对象:为目标对象创建一个代理对象
     */
    @Override
    public Object plugin(Object target) {
        // TODO Auto-generated method stub
        //我们可以借助Plugin的wrap方法来使用当前Interceptor包装我们目标对象
        System.out.println("MyFirstPlugin...plugin:mybatis将要包装的对象"+target);
        Object wrap = Plugin.wrap(target, this);
        //返回为当前target创建的动态代理
        return wrap;
    }

    /**
     *  将插件注册时 的property属性设置进来
     */
    @Override
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub
        System.out.println("插件配置的信息:"+properties);
    }

 

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

<!--plugins:注册插件  -->
    <plugins>
        <plugin interceptor="com.mybatis.dao.MyFirstPlugin">
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </plugin>
        <plugin interceptor="com.mybatis.dao.MySecondPlugin"></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...intercept:"+invocation.getMethod());
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        // TODO Auto-generated method stub
        System.out.println("MySecondPlugin...plugin:"+target);
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub
    }

 总结

  我们可以使用插件为目标对象创建一个代理对象,根据@Signature定义的规则拦截方法的每一个执行。

原文地址:https://www.cnblogs.com/edda/p/13439546.html