Heim > Java > javaLernprogramm > Mybatis-Abfangjäger

Mybatis-Abfangjäger

(*-*)浩
Freigeben: 2019-09-03 16:41:13
nach vorne
2044 Leute haben es durchsucht

Eine der Funktionen von Interceptoren besteht darin, dass wir die Aufrufe bestimmter Methoden abfangen können. Wir können wählen, ob wir vor und nach der Ausführung dieser abgefangenen Methoden etwas Logik hinzufügen oder diese abgefangenen Methoden verwerfen und unsere eigene Logik ausführen können . .

Mybatis-Abfangjäger

Für den Executor von mybatis gibt es beispielsweise mehrere Implementierungen: BatchExecutor, ReuseExecutor, SimpleExecutor und CachingExecutor Schnittstellen können nicht Wenn unsere Anforderungen erfüllt sind, können wir einen Interceptor erstellen, um unsere eigene Abfragemethode zu implementieren. Interceptoren werden im Allgemeinen dynamisch mithilfe von aop implementiert.

Interceptor-Prinzip

Für Mybatis können wir unseren eigenen Interceptor über die Interceptor-Schnittstelle definieren. Definition der Interceptor-Schnittstelle: Die Plugin-Methode

package org.apache.ibatis.plugin;
import java.util.Properties; 
public interface Interceptor { 
    Object intercept(Invocation invocation) throws Throwable; 
    Object plugin(Object target);
    void setProperties(Properties properties);
}
Nach dem Login kopieren

wird hauptsächlich zum Einkapseln des Zielobjekts verwendet. Mit dieser Methode können wir entscheiden, ob das Zielobjekt abgefangen werden soll, und dann entscheiden, welche Art von Zielobjekt zurückgegeben werden soll.

Die Abfangmethode ist die Methode, die beim Abfangen ausgeführt wird. setProperties wird hauptsächlich zum Angeben von Eigenschaften in der Konfigurationsdatei verwendet. Diese Methode wird ausgeführt, wenn die Konfiguration den aktuellen Interceptor initialisiert. Es gibt eine Plugin-Klasse, die die statische Methode Wrap enthält Zurückzugeben sind die Zielobjekte oder Agenten.

package org.apache.ibatis.plugin;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.ibatis.reflection.ExceptionUtil;
 
public class Plugin implements InvocationHandler {
 
    private Object target;
    private Interceptor interceptor;
    private Map<Class<?>, Set<Method>> signatureMap;
 
    private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) {
        this.target = target;
        this.interceptor = interceptor;
        this.signatureMap = signatureMap;
    }
 
    public static Object wrap(Object target, Interceptor interceptor) {
        //解析获取需要拦截的类以及方法{*}
        Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
        Class<?> type = target.getClass();
        //解析type是否存在需要拦截的接口{*}
        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<Method> methods = signatureMap.get(method.getDeclaringClass());
            //如果当前执行的方法是定义的需要拦截的方法,则把目标对象,要拦截的方法以及参数封装为一个Invocation对象传递给拦截器方法intercept;
            //Invocation中定义了定义了一个proceed方法,其逻辑就是调用当前方法,所以如果在intercept中需要继续调用当前方法的话可以调用invocation的procced方法;
            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);
        }
    }
 
    //根据注解解析需要拦截的方法
    //两个重要的注解:@Intercepts以及其值其值@Signature(一个数组)
    //@Intercepts用于表明当前的对象是一个Interceptor
    //@Signature则表明要拦截的接口、方法以及对应的参数类型。
    private static Map<Class<?>, Set<Method>> 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<Class<?>, Set<Method>> signatureMap = new HashMap<Class<?>, Set<Method>>();
        for (Signature sig : sigs) {
            Set<Method> methods = signatureMap.get(sig.type());
            if (methods == null) {
                methods = new HashSet<Method>();
                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<Class<?>, Set<Method>>  signatureMap) {
        Set<Class<?>> interfaces = new HashSet<Class<?>>();
        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()]);
    }
}
Nach dem Login kopieren

Interceptor-Instanz

package com.mybatis.interceptor;
 
import java.sql.Connection;
import java.util.Properties;
 
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
 
@Intercepts( {
@Signature(method = "query", type = Executor.class, args = {
MappedStatement.class, Object.class, RowBounds.class,
ResultHandler.class })}) 
public class TestInterceptor implements Interceptor {
    public Object intercept(Invocation invocation) throws Throwable {
        Object result = invocation.proceed();
        return result;
    }
 
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
 
    public void setProperties(Properties properties) {
        String p = properties.getProperty("property");
    }
}
Nach dem Login kopieren

Markieren Sie dies zuerst als Interceptor mit @Intercepts und entwerfen Sie den Abfangpunkt über @Signatrue: Der Parametertyp in der Interceptor-Executor-Schnittstelle ist MappedStatement, die Abfragemethode von Object, RowBounds und ResultHandler; die Intercept-Methode ruft die Continue-Methode des Aufrufs auf, um den aktuellen Methodenaufruf normal durchzuführen.

Registrierung von Interceptoren

Die Registrierung von Interceptoren erfolgt über das Plugin-Element unter dem Plugins-Element in der Mybatis-Konfigurationsdatei, das in der Registrierung definiert ist Bei Verwendung eines Interceptors werden alle Eigenschaften unter dem entsprechenden Interceptor zunächst über die setProperties-Methode des Interceptors injiziert. Zum Beispiel:

<plugins>
    <plugin interceptor="com.mybatis.interceptor.TestInterceptor">
        <property name="property" value="拦截器配置"/>
    </plugin>
</plugins>
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonMybatis-Abfangjäger. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:csdn.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage