前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊dubbo的ClassLoaderFilter

聊聊dubbo的ClassLoaderFilter

原创
作者头像
code4it
发布2019-06-29 22:36:53
6910
发布2019-06-29 22:36:53
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下dubbo的ClassLoaderFilter

ClassLoaderFilter

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

代码语言:javascript
复制
@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

代码语言:javascript
复制
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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ClassLoaderFilter
  • 实例
  • 小结
  • doc
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档