Plug in mechanism of mybatis

Posted by Confusion101 on Mon, 03 Jan 2022 00:04:12 +0100

In this article, let's talk about the plug-in mechanism of mybatis, which is based on myabtis 3.4 Version 6.

Knowledge points

  • What is a plug-in
  • How to customize plug-ins
  • Plug in implementation principle

What is a plug-in

I believe you must have used many plug-ins, such as eclipse Plug-in, idea plug-in, chrome browser plug-in, etc. in short, plug-in is an extension. It does not belong to the core function. Without it, it does not affect our normal use. With it, we can use it more conveniently, which is icing on the cake. Following references Know an article Some contents:

If the main program wants its own functions to be extended, it needs:

  1. Provides a set of service interfaces. The finer the service definition, the smaller the granularity of plug-in control, the greater the capability, but the higher the coupling and complexity.
  2. An extension contract (plug in interface) is defined, which describes how the plug-in should be designed to facilitate the discovery of the main program. Plug in management module (plug in manager) is used to discover and maintain plug-ins. Plug ins identify themselves by implementing the extension contract (usually an interface) specified by the main program, and receive event responses from the main program. They interact with the main program by mobilizing the services provided by the main program. This process is usually encapsulated by the main program in the form of SDK (Software Development Kit).

A good product must have a flexible extension mechanism. As the persistence framework most used by domestic Internet companies, mybatis naturally provides a set of extension mechanism, that is, plug-ins.

How to customize plug-ins

After introducing the concept of plug-ins, let's take a look at how to customize plug-ins in mybatis. At present, mybatis supports four types of plug-ins: Executor, StatementHandler, ResultSetHandler and ParameterHandler. What do you mean? That is to say, at present, we can only intercept these four types of methods in our custom plug-ins, which basically covers parameterization, before and after sql execution, and result set processing. There are so many core logic of mybatis, so it is enough. Let's define a plug-in to intercept the Executor and print "hello" before query.

1) First define a class to implement the interceptor function

public class MyPlugin implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        return null;
    }

    @Override
    public Object plugin(Object o) {
        return null;
    }

    @Override
    public void setProperties(Properties properties) {
    }
}
Copy code

2) Because we want to intercept the Executor's query, we add the corresponding interception annotation on it. Of course, we can intercept multiple interfaces here

@Intercepts(
        value = {
                @Signature(type = Executor.class, method = "query", args={MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
        }
)
public class MyPlugin implements Interceptor {
   ...
}
Copy code

3) Add a Properties type member to receive the value set in the configuration and output the corresponding content in the configuration before executing the specific operation. Of course, you can also write the output hello directly

@Intercepts(
        value = {
                @Signature(type = Executor.class, method = "query", args={MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
        }
)
public class MyPlugin implements Interceptor {
    private Properties properties = new Properties();

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println(properties.getProperty("output"));
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object o) {
        return Plugin.wrap(o, this);
    }

    @Override
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}
Copy code

4) Add interceptors in the xml configuration file. At present, only xml is supported to configure interceptors. This needs to be supported by subsequent versions of mybatis spring. Note that there are sequence requirements here. The plugins tag should be placed before the mappers tag

    <plugins>
        <plugin interceptor="com.example.mybatisanalyze.plugin.MyPlugin">
            <property name="output" value="hello"/>
        </plugin>
    </plugins>
Copy code

5) Finally, we execute the following procedure to see if the corresponding results are output

You can see that it intercepts and outputs the results we expect.

Plug in implementation principle

The plug-in mechanism is so flexible, how is mybatis implemented? Let's uncover the mystery of the mybatis plug-in mechanism. First, let's look at a picture

Here is the code logic related to all plug-ins, and the Interceptor interface we want to implement

The intercept method is the point where we define the specific embedded logic. All plug-ins are registered and managed uniformly through InterceptorChain

interceptors manage all plug-ins, and the pluginAll method encapsulates the object. Intercepts and Signature are used to customize the methods of the classes to be intercepted. The core logic is in Plugin

You can see that this is mainly done by dynamic agents based on jdk. Combing the whole process with examples

1) When we open the session, we will create an executor. When we create it, mybatis will add a layer of plug-in agent to the executor

2) In the plugin function of the interceptor implemented by ourselves, we call {plugin Wrap has a layer of encapsulation

It will parse our class signature to confirm the methods of the class to be represented. The parsing logic is at org. Org apache. ibatis. plugin. Plugin #getsignaturemap, in our example, intercepts the query method of the Executor

3) When we execute the query logic, the agent goes to the interception method

summary

The plug-in mechanism of mybatis is still very simple as a whole. We can also refer to the plug-in when developing our own.

Topics: Java intellij-idea