Hay muchos principiantes de Java que no saben mucho sobre el Interceptor Interceptor MyBatis. Aquí organizaré el próximo artículo para que explique el Interceptor Interceptor MyBatis en Java.
Este artículo analiza principalmente el mecanismo de complemento de MyBatis, que en realidad es la implementación del modelo de cadena de responsabilidad del proxy dinámico Java.
Según la documentación oficial. MyBatis solo permite interceptar los siguientes métodos, lo que determina los parámetros de firma de la anotación del interceptor.
El código es el siguiente
Ejecutor (Actualización, consulta, Flushstatements, Commit, Rollback, GetTransaction, Close, ISClose) ParameterHandler (getParameteroBject, setParameters) Resultados de Ethandler (HandLerEdSets, HandleOutputParameters) DeclarationHandler (Preparar, Parametrizar, Batch, Update, consulta)
El código fuente del procesamiento del interceptor es el siguiente, donde InterceptorChain.pluginall (..) es un tejido de interceptor personalizado:
El código es el siguiente
/ * Método en org.apache.ibatis.session.Configuration Class */public ParameterHandler NewParameterHandler (MappedStatement MappedStatement, Object ParameterObject, Boundsql BoundSQL) {ParameterHandler ParameterHandler = MappedStatement.getLang (). CreateParameterHandler (mappesStatement, parameterHandler, BoundStatement.getLang (). CreateParameterHandler (mappesStatement, parameterOnsHandler, BoundStatement. /* Intercept ParameterHandler*/ ParameterHandler = (ParameterHandler) InterceptorChain.plugInall (ParameterHandler); return ParameterHandler;} Public ResultsThandler NewResultSethandler (Ejecutor Ejecutor, MappedStatement MapedStatement, RowBounds RowBounds, ParameterHandler ParameterHandler, ResulThandler ResulThandler, Boundsql BoundSQL) {Resultados de los resultados de la Ejecutación = New AfaultresultsetHandler (Ejecutor, MapatéTER, MAPERSHANTLER, PARMAMETERSHANTLER, PARMAMETHERSHANDLER, PAREMETERSHANTLER, ParametRater, ParametRentShandler, ParametRan Resulthandler, BoundSQL, RowBounds); /* Interceptar los resultados deThandler*/ ResultSethandler = (ResultSethandler) Interceptorchain.Pluginall (ResultsThandler); return resultadosethandler;} public DeclarationHandler NewStatementHandler (ejecutor ejecutor, mappedStatement mappedStatement, object parametreObject, rowbounds rowbounds, resulThandler resulThandler, boundsql boundsql) {DeclaryHandler DeclaryLer = New RoutingStatementHandler (ejecutor, ejecutor, mappedStatement, parametEROrtObject, RowBounds, RowBounds, ROWBODSHAY boundsql); /* Intercept DeclarationHandler*/ DeclaryHandler = (DeclarationHandler) Interceptorchain.plugInall (DeclarationHandler); return DeclarationHandler;} public Ejecutor NewExecutor (Transaction Transaction, ExecToType ExecutyPy) {ExecToType = ExecToType == NULL? DefaultExeCutortype: Executortype; ejecutype = ejecutorType == null? Ejecutype.simple: ejecutorType; Albacea; if (ejecutype.batch == Ejecutype) {Ejecutor = new BatchExecutor (this, transacción); } else if (ejecutype.reuse == ejecutortype) {ejecutor = new ReuseExeCutor (this, transacción); } else {ejecutor = new SimpleExecutor (this, transacción); } if (cacheenable) {ejecutor = new CachingExecutor (ejecutor); } /* Intercept Ejecutor* / Ejecutor = (Ejecutor) InterceptorChain.plugInall (Ejecutor); devolver ejecutor;} Para implementar un interceptor personalizado, solo necesita implementar la interfaz de interceptor. El código general es el siguiente:
El código es el siguiente
/* El método y los parámetros de la anotación que indican qué interfaz interceptar*/ @intercepts ({@signature (type = stattleHandler.class, método = "preparar", args = {conecte.class})}) clase pública suinterceptor implementa el interceptor {interceptora pública de objetos (invocación de invocación) lanza el lanzamiento de lanzamiento {Dosming (); / * NOTA: Aquí, el método Invocation.proced () en realidad se usa para completar la llamada transversal de la cadena InterceptorChain (es decir, para ejecutar todos los métodos de intercepción registrados del interceptor) y a la llamada del método original del objeto proxy final */ return Invocation.proceed (); } / * Genere un proxy en el objetivo de destino, y la anotación de @intercepts se usa en plugin.wrap * / @Override Public Object Plugin (objetivo de objeto) { / * Cuando la clase de destino es de Tipo de DeclarationHandler, la clase de destino está envuelta y no se usa proxy sin sentido * / return (Target INSTITISOF Declaratler)? Plugin.wrap (objetivo, este): Target; } /* Se utiliza para establecer parámetros de configuración de interceptor personalizados* / @Override public void setProperties (propiedades de propiedades) {}} Entre ellos, el código para interceptar llamadas está en Plugin.wrap:
El código es el siguiente
/* org.apache.ibatis.plugin.plugin class*/public class El complemento implementa InvocationHandler {/* omitir el código ...*/public static Object wrap (objetivo de objeto, interceptor interceptor) {/* Aquí está para obtener la firma de anotación del interceptor*/map <class <?>, establecer <método >> firmap = getSignemap (interceptor) (interceptor); Clase <?> Type = target.getClass (); /* Obtenga la interfaz que coincida con la clase de destino*/ class <?> [] Interfaces = getAllInterfaces (type, SignaturMap); if (interfaces.length> 0) { /* use jdk dinámico proxy* / return proxy.newproxyInstance (type.getClassLoader (), interfaces, nuevo complemento (Target, Interceptor, SignatureMap)); } objetivo de retorno; } /* La ejecución de todos los métodos de la clase de destino Intercept se ejecutará aquí* / @Override Public Object Invoke (Object Proxy, Method Method, Object [] args) lanza {try {set <ethethod> métodos = signatureMap.get (método.getDeclaringClass ()); if (métodos! = null && métodss.contains (método)) { /* ejecutar el método interceptor* / return interceptor.intercept (nueva invocación (objetivo, método, args)); } return Method.Invoke (Target, Args); } catch (Exception e) {Throw ExceptionUtil.unwrapThrowable (e); }} / * Omitir el código ... * /}Puede ver que el código central del diseño de MyBatis Interceptor es relativamente simple, pero es lo suficientemente flexible. Cuando lo use en la práctica, tenga cuidado de no ser proxy sin sentido (plugin.wrap).