All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.manymobi.esdsl.handler.impl.EsdslInvocationHandler Maven / Gradle / Ivy

package com.manymobi.esdsl.handler.impl;

import com.manymobi.esdsl.handler.MethodHandler;

import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Map;

/**
 * @author 梁建军
 * 创建日期: 2018/11/8
 * 创建时间: 15:02
 * @version 1.0
 * @since 1.0
 */
public class EsdslInvocationHandler implements InvocationHandler {

    private final Map dispatch;


    public EsdslInvocationHandler(Map dispatch) {
        this.dispatch = dispatch;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        } else if (isDefaultMethod(method)) {
            return invokeDefaultMethod(proxy, method, args);
        }

        return dispatch.get(method).invoke(args);
    }

    private Object invokeDefaultMethod(Object proxy, Method method, Object[] args)
            throws Throwable {
        final Constructor constructor = MethodHandles.Lookup.class
                .getDeclaredConstructor(Class.class, int.class);
        if (!constructor.isAccessible()) {
            constructor.setAccessible(true);
        }
        final Class declaringClass = method.getDeclaringClass();
        return constructor
                .newInstance(declaringClass,
                        MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED
                                | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC)
                .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args);
    }

    /**
     * Backport of java.lang.reflect.Method#isDefault()
     *
     * @param method 方法名称
     * @return true 默认方法
     */
    public static boolean isDefaultMethod(Method method) {
        return (method.getModifiers()
                & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) == Modifier.PUBLIC
                && method.getDeclaringClass().isInterface();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy