返回顶部
首页 > 资讯 > 后端开发 > JAVA >mybatis拦截器
  • 238
分享到

mybatis拦截器

java教程java 2018-10-19 07:10:31 238人浏览 绘本
摘要

拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,或者丢弃这些被拦截的方法而执行自己的逻辑。如对于mybatis的Executor,有几种实现:BatchExecutor,ReuseExec

拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,或者丢弃这些被拦截的方法而执行自己的逻辑。

如对于mybatis的Executor,有几种实现:BatchExecutor,ReuseExecutor、SimpleExecutor和CachingExecutor,当这几种Executor接口的query方法无法满足我们的要求的时候,我们就可以建立一个拦截器来实现自己的query方法;拦截器一般采用aop动态实现。

拦截器原理

对于mybatis,我们可以通过interceptor接口定义自己的拦截器。interceptor接口定义:

package org.apache.ibatis.plugin;
import java.util.Properties; 
public interface Interceptor { 
    Object intercept(Invocation invocation) throws Throwable; 
    Object plugin(Object target);
    void setProperties(Properties properties);
}

plugin方法主要是用于封装目标对象,通过该方法我们可以决定是否要进行拦截进而决定返回什么样的目标对象。

intercept方法就是要进行拦截的时候执行的方法。setProperties主要用于在配置文件中指定属性,这个方法在Configuration初始化当前的Interceptor时就会执行.在mybatis中有一个plugin类,该类包括静态方法wrap,通过该方法可以决定需要返回的对象是目标对象还是代理。

package org.apache.ibatis.plugin;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.ibatis.reflection.ExceptionUtil;
 
public class Plugin implements InvocationHandler {
 
    private Object target;
    private Interceptor interceptor;
    private Map, Set> signatureMap;
 
    private Plugin(Object target, Interceptor interceptor, Map, Set> signatureMap) {
        this.target = target;
        this.interceptor = interceptor;
        this.signatureMap = signatureMap;
    }
 
    public static Object wrap(Object target, Interceptor interceptor) {
        //解析获取需要拦截的类以及方法{*}
        Map, Set> signatureMap = getSignatureMap(interceptor);
        Class type = target.getClass();
        //解析type是否存在需要拦截的接口{*}
        Class[] interfaces = getAllInterfaces(type, signatureMap);
        //决定返回的对象是否为代理{*}
        if (interfaces.length > 0) {
            return Proxy.newProxyInstance(
                type.getClassLoader(),
                interfaces,
                new Plugin(target, interceptor, signatureMap));
        }
        //返回原目标对象
        return target;
    }
 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            Set methods = signatureMap.get(method.getDeclarinGClass());
            //如果当前执行的方法是定义的需要拦截的方法,则把目标对象,要拦截的方法以及参数封装为一个Invocation对象传递给拦截器方法intercept;
            //Invocation中定义了定义了一个proceed方法,其逻辑就是调用当前方法,所以如果在intercept中需要继续调用当前方法的话可以调用invocation的procced方法;
            if (methods != null && methods.contains(method)) {
                return interceptor.intercept(new Invocation(target, method, args));
            }
            return method.invoke(target, args);
        } catch (Exception e) {
            throw ExceptionUtil.unwrapThrowable(e);
        }
    }
 
    //根据注解解析需要拦截的方法
    //两个重要的注解:@Intercepts以及其值其值@Signature(一个数组)
    //@Intercepts用于表明当前的对象是一个Interceptor
    //@Signature则表明要拦截的接口、方法以及对应的参数类型。
    private static Map, Set> getSignatureMap(Interceptor interceptor) {
        Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);
        if (interceptsAnnotation == null) { // issue #251
            throw new PluginException("No @Intercepts annotation was found in interceptor " + interceptor.getClass().getName());
        }
        Signature[] sigs = interceptsAnnotation.value();
        Map, Set> signatureMap = new HashMap, Set>();
        for (Signature sig : sigs) {
            Set methods = signatureMap.get(sig.type());
            if (methods == null) {
                methods = new HashSet();
                signatureMap.put(sig.type(), methods);
            }
            try {
                Method method = sig.type().getMethod(sig.method(), sig.args());
                methods.add(method);
            } catch (NoSuchMethodException e) {
                throw new PluginException("Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e, e);
            }
        }
        return signatureMap;
    }
 
    private static Class[] getAllInterfaces(Class type, Map, Set>  signatureMap) {
        Set> interfaces = new HashSet>();
        while (type != null) {
            for (Class c : type.getInterfaces()) {
                if (signatureMap.containsKey(c)) {
                    interfaces.add(c);
                }
            }
            type = type.getSuperclass();
        }
        return interfaces.toArray(new Class[interfaces.size()]);
    }
}

拦截器实例

package com.mybatis.interceptor;
 
import java.sql.Connection;
import java.util.Properties;
 
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
 
@Intercepts( {
@Signature(method = "query", type = Executor.class, args = {
MappedStatement.class, Object.class, RowBounds.class,
ResultHandler.class })}) 
public class TestInterceptor implements Interceptor {
    public Object intercept(Invocation invocation) throws Throwable {
        Object result = invocation.proceed();
        return result;
    }
 
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
 
    public void setProperties(Properties properties) {
        String p = properties.getProperty("property");
    }
}

首先用@Intercepts标记了这是一个Interceptor,通过@Signatrue设计拦截点:拦截Executor接口中参数类型为MappedStatement、Object、RowBounds和ResultHandler的query方法;intercept方法调用invocation的proceed方法,使当前方法正常调用。

拦截器的注册

注册拦截器是通过在Mybatis配置文件中plugins元素下的plugin元素来进行的,Mybatis在注册定义的拦截器时会先把对应拦截器下面的所有property通过Interceptor的setProperties方法注入。如:


    
        
    

--结束END--

本文标题: mybatis拦截器

本文链接: https://lsjlt.com/news/3613.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • mybatis拦截器
    拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,或者丢弃这些被拦截的方法而执行自己的逻辑。如对于mybatis的Executor,有几种实现:BatchExecutor,ReuseExec...
    99+
    2018-10-19
    java教程 java
  • MyBatis 拦截器介绍
    MyBatis 拦截器介绍 MyBatis 提供了一种插件 (plugin) 的功能,虽然叫做插件,但其实这是拦截器功能。那么拦截器拦截 MyBatis 中的哪些内容呢? 我们进入官网看一看: MyBatis 允许你在已映射语句执行过程中的...
    99+
    2023-09-02
    mybatis java mysql 拦截器
  • mybatis拦截器怎么使用
    今天小编给大家分享一下mybatis拦截器怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。mybatis实战之拦截器在...
    99+
    2023-07-05
  • mybatis实战之拦截器解读
    目录myBATis实战之拦截器1、使用方法2、需要注意的地方拦截器的执行顺序与常用插件的整合遇到的问题可以提升的点总结mybatis实战之拦截器 在服务的开发过程中,往往存在这样的需求,针对业务,实现对数据库操作语句做统...
    99+
    2023-03-20
    mybatis拦截器 拦截器 mybatis实战
  • Mybatis拦截器打印sql问题
    目录1.log4j2配置修改2.配置日志开关3.添加拦截器插件4.拦截器逻辑描述4.1 注入开关4.2 获取sql4.2 获取参数4.3 sql替换参数4.4 打印sql4.5打印效...
    99+
    2023-05-13
    Mybatis拦截器打印sql Mybatis拦截器 拦截器打印sql
  • MyBatis拦截器的实现原理
    目录前言 1.使用方法2.MyBatis对象的创建3.代理对象的创建3.1 拦截器的获取3.2 代理对象的创建4. 拦截器的执行过程5. 拦截器的执行顺序前言 Mybati...
    99+
    2024-04-02
  • MyBatis拦截器的原理与使用
    目录一、拦截对象和接口实现示例二、拦截器注册的三种方式        1.XML注册  &n...
    99+
    2024-04-02
  • MyBatis Excutor 拦截器的巧妙用法
    这里要讲的巧妙用法是用来实现在拦截器中执行额外 MyBatis 现有方法的用法。并且会提供一个解决拦截Executor时想要修改MappedStatement时解决并发的问题。这里假设一个场景:实现一个拦截器,记录 MyBatis 所有的 ...
    99+
    2023-05-31
    mybatis excutor 拦截器
  • 【mybatis】mybatis 拦截器工作原理源码解析
    mybatis 拦截器工作原理(JDK动态代理) 1. mybatis 拦截器案例 场景:分页查询,类似成熟产品:pagehelper, 这里只做简单原理演示 1.0 mybatis全局配置 SqlMapConfig.xml ...
    99+
    2015-01-18
    【mybatis】mybatis 拦截器工作原理源码解析
  • Mybatis-Plus实现SQL拦截器的示例
    目录起源实现拦截器接口InnerInterceptor修改sql常用的工具类起源 最近公司要做多租户,Mybatis-Plus的多租户插件很好用,但是有一个场景是:字典表或者某些数据...
    99+
    2023-05-19
    Mybatis-Plus SQL拦截器 Mybatis-Plus 拦截器
  • Mybatis拦截器实现自定义需求
    目录前言一、应用场景二、Mybatis实现自定义拦截器2.1、编写拦截器2.2、添加到Mybatis配置2.3、测试2.4、小结三、拦截器接口介绍intercept 方法plugin...
    99+
    2023-05-19
    Mybatis自定义拦截器 Mybatis 拦截器
  • 在springboot中如何给mybatis加拦截器
    目录1、实现Interceptor接口,并添加拦截注解 @Intercepts1.在mybatis中可被拦截的类型有四种(按照拦截顺序)2.各个参数的含义2、在配置文件中添加拦截器(...
    99+
    2024-04-02
  • SpringBoot拦截器实现登录拦截
    SpringBoot拦截器可以做什么可以对URL路径进行拦截,可以用于权限验证、解决乱码、操作日志记录、性能监控、异常处理等。SpringBoot拦截器实现登录拦截pom.xml: 4.0.0 org.s...
    99+
    2015-07-20
    java教程 Spring Boot java
  • 使用mybatis拦截器处理敏感字段
    目录mybatis拦截器处理敏感字段前言思路解析代码趟过的坑(敲黑板重点)mybatis Excutor 拦截器的使用这里假设一个场景实现过程的关键步骤和代码重点mybatis拦截器...
    99+
    2024-04-02
  • Springboot如何实现自定义mybatis拦截器
    这篇文章将为大家详细讲解有关Springboot如何实现自定义mybatis拦截器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。实践的准备 : 整合mybatis ,然后故意写了3个查询方法, ...
    99+
    2023-06-22
  • MyBatis拦截器怎么动态替换表名
    本篇内容主要讲解“MyBatis拦截器怎么动态替换表名”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MyBatis拦截器怎么动态替换表名”吧!一、Mybatis Interceptor 拦截器接...
    99+
    2023-06-30
  • 利用Mybatis Plus实现一个SQL拦截器
    目录起源实现拦截器接口InnerInterceptor修改sql常用的工具类起源 最近公司要做多租户,Mybatis-Plus的多租户插件很好用,但是有一个场景是:字典表或者某些数据...
    99+
    2023-05-19
    Mybatis Plus实现SQL拦截器 Mybatis Plus SQL拦截 Mybatis Plus SQL
  • MyBatis自定义SQL拦截器示例详解
    目录前言定义是否开启注解注册SQL 拦截器处理逻辑如何使用总结前言 本文主要是讲通过 MyBaits 的 Interceptor 的拓展点进行对 MyBatis 执行 SQL 之前做...
    99+
    2024-04-02
  • Springboot自定义mybatis拦截器实现扩展
    前言 相信大家对拦截器并不陌生,对mybatis也不陌生。 有用过pagehelper的,那么对mybatis拦截器也不陌生了,按照使用的规则触发sql拦截,帮我们自动添加分页参数 ...
    99+
    2024-04-02
  • MyBatis拦截器实现分页功能实例
    由于业务关系 巴拉巴拉巴拉好吧 简单来说就是原来的业务是 需要再实现类里写 selectCount 和selectPage两个方法才能实现分页功能现在想要达到效果是 只通过一个方法就可以实现 也就是功能合并 所以就有了下面的实践既然是基于M...
    99+
    2023-05-31
    mybatis 拦截器 分页
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作