聊聊dubbo的ClassLoaderFilter

聊聊dubbo的ClassLoaderFilter

本文主要研究一下dubbo的ClassLoaderFilter

ClassLoaderFilter

dubbo-2.7.2/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ClassLoaderFilter.java

@Activate(group = CommonConstants.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);

}

}

}

ClassLoaderFilter实现了Filter界面,其invoke方法首先获取当前执行绪的contextClassLoader,然后将其ContextClassLoader设定为invoker.getInterface().getClassLoader(),之后执行invoker.invoke方法,最后将当前执行绪的classLoader重置为原来的contextClassLoader例项

dubbo-2.7.2/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ClassLoaderFilterTest.java

public class ClassLoaderFilterTest {

private ClassLoaderFilter classLoaderFilter = new ClassLoaderFilter();

@Test

public void testInvoke() throws Exception {

URL url = URL.valueOf(test://test:11/test?accesslog=true&group=dubbo&version=1.1);

String path = DemoService.class.getResource(/).getPath();

final URLClassLoader cl = new URLClassLoader(new java.net.URL[]{new java.net.URL(file: + path)}) {

@Override

public Class> loadClass(String name) throws ClassNotFoundException {

try {

return findClass(name);

} catch (ClassNotFoundException e) {

return super.loadClass(name);

}

}

};

final Class> clazz = cl.loadClass(DemoService.class.getCanonicalName());

Invoker invoker = new MyInvoker(url) {

@Override

public Class getInterface() {

return clazz;

}

@Override

public Result invoke(Invocation invocation) throws RpcException {

Assertions.assertEquals(cl, Thread.currentThread().getContextClassLoader());

return null;

}

};

Invocation invocation = Mockito.mock(Invocation.class);

classLoaderFilter.invoke(invoker, invocation);

}

}

这里invoker的interface设定为DemoService.class,然后验证invoke方法里头的Thread.currentThread().getContextClassLoader()为载入DemoService.class的URLClassLoader小结

ClassLoaderFilter实现了Filter界面,其invoke方法首先获取当前执行绪的contextClassLoader,然后将其ContextClassLoader设定为invoker.getInterface().getClassLoader(),之后执行invoker.invoke方法,最后将当前执行绪的classLoader重置为原来的contextClassLoader

doc

ClassLoaderFilter

猜你喜欢