Dubbo 소스 분석 - 필터 (1) 의 ClassLoader Filter

1. 개요


ProtocolFilterWrapper에서 서비스 인용과 노출 시 #buildInvokerChain(invoker,key,group) 방법은 Dubbo SPI Active 메커니즘을 바탕으로 일치하는 필터 그룹을 불러오고 필터 체인이 있는 Invoker 대상을 만듭니다.코드는 다음과 같습니다.
/**
 *   Filter   Invoker  
 *
 * @param invoker Invoker  
 * @param key   URL  
 * @param group  
 * @param   
 * @return Invoker  
 */
private static  Invoker buildInvokerChain(final Invoker invoker, String key, String group) {
    Invoker last = invoker;
    //  
    List filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
    //   Filter ,  Filter   Invoker  
    if (!filters.isEmpty()) {
        for (int i = filters.size() - 1; i >= 0; i--) {
            final Filter filter = filters.get(i);
            final Invoker next = last;
            last = new Invoker() {

                @Override
                public Class getInterface() {
                    return invoker.getInterface();
                }

                @Override
                public URL getUrl() {
                    return invoker.getUrl();
                }

                @Override
                public boolean isAvailable() {
                    return invoker.isAvailable();
                }

                @Override
                public Result invoke(Invocation invocation) throws RpcException {
                    return filter.invoke(next, invocation);
                }

                @Override
                public void destroy() {
                    invoker.destroy();
                }

                @Override
                public String toString() {
                    return invoker.toString();
                }
            };
        }
    }
    return last;
}

2.ClassLoaderFilter


Filter 인터페이스를 구현하고 클래스 로더에서 필터 구현 클래스를 전환합니다.코드는 다음과 같습니다.
@Activate(group = Constants.PROVIDER, order = -30000)
public class ClassLoaderFilter implements Filter {

    @Override
    public Result invoke(Invoker> invoker, Invocation invocation) throws RpcException {
        //  
        ClassLoader ocl = Thread.currentThread().getContextClassLoader();
        //  
        Thread.currentThread().setContextClassLoader(invoker.getInterface().getClassLoader());
        //  
        try {
            return invoker.invoke(invocation);
        } finally {
            //  
            Thread.currentThread().setContextClassLoader(ocl);
        }
    }

}

설계 목적에서 인터페이스에 정의된 클래스 캐리어를 불러오는 것으로 전환하여 같은 클래스 캐리어의 상하문과 함께 작업을 할 수 있도록 한다.

좋은 웹페이지 즐겨찾기