스스로 Dubbo Invoker 실현

23932 단어 자기가 쓴 틀
1. Dubbo Invoker 는 spring 이 주입 한 업무 인터페이스의 실현 류 를 수행 하 는 방법 입 니 다.다음은 내 가 알 아서 할 게.기본적으로 dubbo 의 디자인 모델 사상 이다.
2. 사용 설명 보기:
//User   
class User {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
//    user  
interface IUserSerice {
    public User login(User user);
}
//     
class UserServiceImpl implements IUserSerice {
    @Override
    public User login(User user) {
        System.err.println(user.getName() + " login....");
        user.setName("login success");
        return user;
    }
}
 public static void main(String[] args) {
         //   spring new     
        IUserSerice userSerice = new UserServiceImpl();
        User user = new User();
        user.setName("hadluo");
        //     IUserSerice        Invoker ,dubbo extensionloader   ,        .
        Invoker invoker = JavassistProxyFactory.getInvoker(userSerice, IUserSerice.class);
        //        ,Invocation       ,      login    
        Invocation invocation = new NativeInvocation("login",new Class>[]{User.class},new Object[]{user}) ;
        //         
        Result result = invoker.invoker(invocation);
        System.err.println("    :" + ((User)result.getResult()).getName());
    }
//###########  
hadluo login....
   :login success

세부 사항
JavassistProxy Factory 는 Invoker (실행 기) 를 구성 하 는 데 사 용 됩 니 다. dubbo 는 ExtensionLoader 로 JavassistProxy Factory 를 구성 합 니 다. ExtensionLoader 의 실현 은 다른 편 을 볼 수 있 습 니 다.https://blog.csdn.net/luozheng4698729/article/details/80070630
public class JavassistProxyFactory {
    // proxy: UserServiceImpl     , type: IUserService   class
    public static  Invoker getInvoker(T proxy, Class> type) {
        // Wrapperd    IUserService        ,     
        final Wrapper wrapper = Wrapper.getWrapper(type);
        return new AbstractProxyInvoker(type, proxy) {
            @Override
            public Object doInvoke(Object proxy, Invocation invocation) throws Throwable {
                return wrapper.invokeMethod(proxy, invocation.getMethodName(),
                        invocation.getParameterTypes(), invocation.getArguments());
            }
        };
    }
 }

Invoker 실행 기 인터페이스
public interface Invoker{
    //     , Invocation      (         ,     ),Result     
    Result invoker(Invocation invocation);
    //      dubbo    
}

Invocation 실행 방법 정보, dubbo 에는 로 컬 방법 실행 정보 유형 과 RPC 방법 실행 정보 유형 이 포함 되 어 있 습 니 다.
/***
 *         (  ,   ,   )
 * 
 * @author HadLuo
 * @since JDK1.7
 * @history 2018 4 27    
 */
public interface Invocation {
    //          
    String getMethodName();
    //           
    Class>[] getParameterTypes();
    //       
    Object[] getArguments();
}
//             ,       
public class NativeInvocation implements Invocation {
    private String methodName;
    private Class>[] parameterTypes;
    private Object[] arguments;
    public NativeInvocation(String methodName, Class>[] parameterTypes, Object[] arguments) {
        super();
        this.methodName = methodName;
        this.parameterTypes = parameterTypes;
        this.arguments = arguments;
    }
    @Override
    public String getMethodName() {
        return methodName;
    }
    @Override
    public Class>[] getParameterTypes() {
        return parameterTypes;
    }
    @Override
    public Object[] getArguments() {
        return arguments;
    }
}

Result 실행 기 Invoker 의 실행 결 과 는 Invocation 과 대응 합 니 다. 로 컬 실행 결과, rpc 실행 결 과 를 포함 합 니 다.
/***
 *    Invoker      
 * 
 * @author HadLuo
 * @since JDK1.7
 * @history 2018 4 27    
 */
public interface Result {
    public Object getResult();
}
//                   
public class RpcResult implements Result {
    private Object object;

    public RpcResult(Object object) {
        this.object = object;
    }
    @Override
    public Object getResult() {
        return object;
    }
}

AbstractProxy Invoker 실행 기 구현, 중요
/***
 *           
 * 
 * @author HadLuo
 * @since JDK1.7
 * @history 2018 4 27    
 */
public abstract class AbstractProxyInvoker<T> implements Invoker<T> {
    // spring       ,       UserServiceImpl  
    private final T object;

    public AbstractProxyInvoker(Class> type, T object) {
        this.object = object;
    }

    /***
     *         ,   Wrapper  
     * 
     * @param proxy
     * @param invocation
     * @return
     * @throws Throwable
     * @author HadLuo 2018 4 27    
     */
    public abstract Object doInvoke(Object proxy, Invocation invocation) throws Throwable;

    @Override
    public Result invoker(Invocation invocation) {
        if (invocation instanceof NativeInvocation) {
            try {
                //      doInvoke   
                return new RpcResult(doInvoke(object, invocation));
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
        if(invocation instanceof RpcInvocation){
            //     ,      
        }
        throw new RuntimeException("               ");
    }
}

Wrapper Wrapper 는 인터페이스 클 라 스 를 포장 하 는 독립 적 인 추상 적 인 클래스 입 니 다. (위 에서 말 한 IUserService)여기 서 class 작업 에 대해 우 리 는 몇 가지 작업 을 추상 화 할 수 있 습 니 다. 1. class 의 모든 필드 의 이름 을 가 져 옵 니 다: abstract Public String [] getProperty Names ();
2. 필드 이름 에 따라 필드 형식 가 져 오기: abstract public Class getProperty Type (String pn);
3. class 에 필드 가 존재 하 는 지 판단 하기: abstract public boolean hasProperty (String name);
4. class 대상 의 필드 값 가 져 오기: abstract public Object getPropertyValue (Object instance, String pn) throws Throwable;
5. 필드 값 설정: abstract public void set PropertyValue (Object instance, String pn, Object pv) throws Throwable;
6. 실행 방법: abstract public Object invokeMethod (Object instance, String methodName, Class [] types, Object [] args) throws Throwable;
6 조 가 중요 한 게 분명 해.실현 원 리 는 바로 동태 적 으로 하나의 Wrapper 의 실현 류 Wrapper 0 을 구성 하여 상기 6 가지 추상 적 인 방법 을 실현 하 는 것 이다. 다음 에 우 리 는 이런 방법 을 어떻게 실현 하 는 지 살 펴 보 자.
public abstract class Wrapper {
    //     ,Wrapper0   0        1,    :Wrapper0,Wrapper1,Wrapper2...
    private static AtomicLong WRAPPER_CLASS_COUNTER = new AtomicLong(0);
    //   , key: IUserService  class, value:    
    private static ConcurrentHashMap, Wrapper> WRAPPERS = new ConcurrentHashMap, Wrapper>();

    public static Wrapper getWrapper(Class> type) {
        Wrapper wrapper = WRAPPERS.get(type);
        if (wrapper == null) {
            //      
            wrapper = makeWrapper(type);
            //    
            WRAPPERS.putIfAbsent(type, wrapper);
        }
        return wrapper;
    }

    abstract public String[] getPropertyNames();

    abstract public Class> getPropertyType(String pn);

    abstract public boolean hasProperty(String name);

    abstract public Object getPropertyValue(Object instance, String pn) throws Throwable;

    abstract public void setPropertyValue(Object instance, String pn, Object pv) throws Throwable;

    abstract public Object invokeMethod(Object instance, String methodName, Class>[] types, Object[] args) throws Throwable;

    private static Wrapper makeWrapper(Class> type) {
        //   ClassGenerator  dubbo         ,  javassist    ,         
        ClassGenerator classGenerator = ClassGenerator.newInstance(Wrapper.class.getClassLoader());
        // extends Wrapper.class
        classGenerator.setSuperClass(Wrapper.class);
        // class   
        classGenerator.setClassName(Wrapper.class.getName() + WRAPPER_CLASS_COUNTER.getAndIncrement() + "$");

        // public static Map> pts; // key:      value:    
        classGenerator.addField("public static " + Map.class.getName() + " pts;");
        //        
        classGenerator.addField("public static String[] pNames;");

        // getPropertyNames       
        classGenerator.addMethod("public String[] getPropertyNames(){return pNames;}");
        // getPropertyType       
        classGenerator.addMethod("public Class getPropertyType(String pName) { return (Class)pts.get(pName); }");
        // hasProperty       
        classGenerator
                .addMethod("public boolean hasProperty(String name){  return pts.containsKey(name) ; }");
        // getPropertyValue       
        classGenerator
                .addMethod("public Object getPropertyValue(Object instance, String pName) throws Throwable { "
                        + "try {"
                        + "java.lang.Class clazz = instance.getClass();"
                        + "java.lang.reflect.Field f = clazz.getDeclaredField(pName);"
                        + "return f.get(instance);" + "} catch (Exception e) {throw e;} }");
        // setPropertyValue       
        classGenerator
                .addMethod("public void setPropertyValue(Object instance, String pName, Object pValue) throws Throwable {"
                        + "try {"
                        + "java.lang.reflect.Field f = instance.getClass().getDeclaredField(pName);"
                        + "f.set(instance, pValue);" + "} catch (Exception e) { throw e;}}");
        // invokeMethod       
        classGenerator
                .addMethod("public Object invokeMethod(Object instance, String methodName, Class[] types, Object[] args) throws Throwable {"
                        + "try {"
                        + "java.lang.Class clazz = instance.getClass();"
                        + "java.lang.reflect.Method method = clazz.getDeclaredMethod(methodName, types);"
                        + "if (method == null) { throw new NullPointerException(\"     \" + clazz.getName() + \"        : \" + methodName);}"
                        + "return method.invoke(instance, args);" + "} catch (Exception e) {throw e;}}");

        try {
            Class> proxyClass = classGenerator.toClass();
            if (proxyClass == null) {
                throw new RuntimeException("        ");
            }
            Map> pts = new HashMap>();
            for (Field f : type.getDeclaredFields()) {
                pts.put(f.getName(), f.getType());
            }
         //              
            proxyClass.getDeclaredField("pts").set(null, pts);
            proxyClass.getDeclaredField("pNames").set(null, pts.keySet().toArray(new String[0]));

            return (Wrapper) proxyClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

상기 동적 구조 류 의 코드 는 깊이 연구 할 필요 가 없다. 사실은 다음 과 같은 유형 을 구성 하 는 것 이다 (실현 도 간단 하 다).
//       ==============
class Wrapper0 extends Wrapper {
    // key:      value:    
    public static Map> pts;
    //     
    public static String[] pNames;
    @Override
    public Object invokeMethod(Object instance, String methodName, Class>[] types, Object[] args)
            throws Throwable {
        try {
            java.lang.Class clazz = instance.getClass();
            java.lang.reflect.Method method = clazz.getDeclaredMethod(methodName, types);
            if (method == null) {
                throw new NullPointerException("     " + clazz.getName() + "        : " + methodName);
            }
            return method.invoke(instance, args);
        } catch (Exception e) {
            throw e;
        }
    }
    @Override
    public String[] getPropertyNames() {
        return pNames;
    }

    @Override
    public Class> getPropertyType(String pName) {
        return pts.get(pName);
    }

    @Override
    public boolean hasProperty(String name) {
        return pts.containsKey(name);
    }

    @Override
    public Object getPropertyValue(Object instance, String pName) throws Throwable {
        try {
            java.lang.Class clazz = instance.getClass();
            java.lang.reflect.Field f = clazz.getDeclaredField(pName);
            return f.get(instance);
        } catch (Exception e) {
            throw e;
        }
    }
    @Override
    public void setPropertyValue(Object instance, String pName, Object pValue) throws Throwable {
        try {
            java.lang.reflect.Field f = instance.getClass().getDeclaredField(pName);
            f.set(instance, pValue);
        } catch (Exception e) {
            throw e;
        }
    }
}

상술 한 것 은 모든 실현 디 테 일 입 니 다. Dubbo 와 약간의 차이 가 있 을 것 입 니 다. 진실 을 따 질 필요 가 없고 주로 사상 이 일치 합 니 다.프로젝트 원본 코드 추가: 657455400 csdn 다운로드 링크:https://download.csdn.net/download/luozheng4698729/10379503

좋은 웹페이지 즐겨찾기