Preface One of the functions of an interceptor is that we can intercept the calls of certain methods. We can choose to add some logic before and after the execution of these intercepted methods, or we can execute our own logic when executing these intercepted methods instead of executing the intercepted methods. One of the original intentions of designing the Mybatis interceptor is to allow users to implement their own logic at certain times without having to change the inherent logic of Mybatis. For example, I want to perform a fixed operation on all SQLs, perform security checks on SQL queries, or record related SQL query logs, etc. Mybatis provides us with an Interceptor interface that can implement a custom interceptor. public interface Interceptor { Object intercept(Invocation invocation) throws Throwable; Object plugin(Object target); void setProperties(Properties properties); } The interface contains three method definitions The intercept method is a specific processing method for the interception object. The passed Invocation contains the strength of the interception target class, the interception method and the input parameter group of the method. Use the Invocation procedure to execute the original function. The plugin determines whether to intercept. If no interception is required, the target is returned directly. If interception is required, the wrap static method in the Plugin class is called. If the current interceptor implements any interface, a proxy object is returned, otherwise it is returned directly (recall the design of the proxy mode). The proxy object is actually an instance of the Plugin class, which implements the InvocationHandler interface. The InvocationHandler interface only contains the invoke method for the callback method. When the interface method of the proxy object is executed, the invoke method of the Plugin is called, which packages the object, method and parameters to be executed into an Invocation object and passes it to the intercept method of the interceptor. Invocation defines a procced method to execute the intercepted original method. Plugin Class Definition 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(); 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()); 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); } } 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()]); } } The setProperties method, as the name suggests, is used to set properties. There are many ways to initialize bean properties, this is one of them. Mybatis provides the @Intercepts annotation to declare that the current class is an interceptor. Its value is an @Signature array, indicating the interface, method, and corresponding parameter type to be intercepted. @Intercepts({@Signature(method = "prepare", type = StatementHandler.class, args = {Connection.class}), @Signature(method = "query", type = StatementHandler.class, args = {java.sql.Statement.class, ResultHandler.class})}) public class TenantInterceptor implements Interceptor { ..... For example, in the above class declaration, the first Signature annotation intercepts the input parameter under the StatementHandler class, which is a Connection method named prepare. The second Signature annotation intercepts the query method in the StatementHandler class that contains two input parameters (of type Statement and ResultHandler). Finally, the declared Interceptor needs to be registered in the mybatis plug to take effect. <!-- Configure mybatis --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/> <!-- mapper scan --> <property name="mapperLocations" value="classpath:mybatis/*/*.xml"/> <property name="plugins"> <array> <!-- Register your own interceptor --> <bean id="paginationInterceptor" class="xxx.xxx.TenantInterceptor"> </bean> </array> </property> </bean> The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM. You may also be interested in:
|
<<: Detailed explanation of the steps of using ElementUI in actual projects
>>: Linux disk management LVM usage
Preface Today, when I was using a self-written co...
Result: Implementation code: html <div class=&...
Summarize Global environment ➡️ window Normal fun...
MySQL Advanced SQL Statements use kgc; create tab...
The application of containers is becoming more an...
This article shares the specific code of the WeCh...
Compared with the old life cycle Three hooks are ...
Table of contents Is setState synchronous or asyn...
1. Create users and authorize Creating users and ...
The article mainly records the simple installatio...
Preface The company's Ubuntu server places th...
This article uses the "Attribution 4.0 Inter...
Table of contents 1 redis configuration file 2 Do...
This article example shares the specific code of ...
This article example shares the specific code of ...