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
You can use the trigger method. There is no native...
Last time we talked about some SQL query optimiza...
Plot Review In the previous article, we analyzed ...
OBS studio is cool, but JavaScript is cooler. Now...
Before understanding this problem, let's firs...
When searching online for methods to install MySQ...
The action of the form is different from the URL j...
Table of contents use Use of EsLint Add a profile...
The database installation tutorial of MySQL-8.0.2...
1. Rendering JD Effect Simulation Effect 2. Princ...
Effect (source code at the end): accomplish: 1. D...
The /partition utilization of a server in IDC is ...
Optimistic Locking Optimistic locking is mostly i...
1. Scroll Snap is a must-have skill for front-end...
You may already know that the length 1 of int(1) ...