This is the third day of my participation in Gwen Challenge

A: background

In general, open source frameworks provide plug-ins or other extensions that developers can extend themselves. The benefits are obvious. One is increased flexibility of the framework. Second, developers can expand the framework based on actual needs to make it work better. Taking MyBatis as an example, we can realize functions such as paging, table splitting and monitoring based on MyBatis plug-in mechanism. Because plug-ins are irrelevant to the business, the business is not aware of the existence of plug-ins. Therefore, plug-ins can be inserted without feeling and enhance functions virtually

Mybatis plug-in introduction

Mybatis is an excellent ORM open source framework widely used, this framework has great flexibility, Easy to use plug-in extension mechanisms are provided in the four major components (Executor, StatementHandler, ParameterHandler, ResultSetHandler). Mybatis operates on the persistence layer with the help of four core objects. MyBatis supports the interception of four core objects by plug-ins. For MyBatis, plug-ins are interceptors, which are used to enhance the functions of core objects. The enhanced functions are essentially realized by means of the underlying dynamic proxy

MyBatis allows the following interception methods:

  • Executor (update, Query, commit, rollback, etc.);
  • SQL syntax builder StatementHandler (prepare, parameterize, Batch, updates query, etc.);
  • ParameterHandler (getParameterObject, setParameters methods);
  • Result set processor ResultSetHandler (handleResultSets, handleOutputParameters, etc.);

Three :Mybatis plug-in principle

When the big four objects are created

  • 1, each of the created object is not returned directly, and interceptorChain. PluginAll (parameterHandler);
  • Get all interceptors (interfaces the plug-in needs to implement); Call interceptor. The plugin (target); Returns the target wrapped object
  • 3. Plugin mechanism, we can use plug-in to create a proxy object for the target object; AOP (aspect oriented) Our plug-in can create proxy objects for each of the four objects, which can intercept each execution of the four objects;

intercept

How exactly does a plug-in intercept and attach additional functionality? In ParameterHandler

public ParameterHandler newParameterHandler(MappedStatement mappedStatement,Object object, BoundSql sql, InterceptorChain interceptorChain){
    ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement,object,sql);
    parameterHandler = (ParameterHandler)
    interceptorChain.pluginAll(parameterHandler);
    return parameterHandler;
}
public Object pluginAll(Object target) {
    for (Interceptor interceptor : interceptors) 
    {
        target = interceptor.plugin(target);
    }
    return target;
}
Copy the code

The interceptorChain holds all interceptors, which are created when mybatis is initialized. Interceptors in the interceptor chain are called to intercept or enhance the target in turn. The target in interceptor.plugin(target) can be understood as the four objects in Mybatis. The target returned is the heavily proxied object

If we wanted to intercept Executor’s Query methods, we could define the plug-in as follows:

@Intercepts({
    @Signature(
        type = Executor.class,
        method = "query",
        args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class}
        )
})
public class ExeunplePlugin implements Interceptor {
// omit logic
}
Copy the code

In addition, we need to configure the plug-in into sqlmapconfig.xml.

<plugins>
    <plugin interceptor="com.lagou.plugin.ExamplePlugin"></plugin>
</plugins>
Copy the code

This allows MyBatis to load the plug-in on startup and save the plug-in instance into the relevant object (InterceptorChain). After the preparation, MyBatis is in a ready state. When executing SQL, we need to create SqlSession through DefaultSqlSessionFactory first. An Executor instance will be created during SqlSession creation. After the Executor instance is created, MyBatis will use JDK dynamic proxy to generate proxy classes for the instance. This way, the plug-in logic can be executed before executor-related methods are called.

This is the basic principle of the MyBatis plugin mechanism.

I hope to be helpful to you