URL类的setURLStreamHandlerFactory支持多个factory的方法

之前碰到一个问题,需要支持hadoop的url,而java的URL类的setURLStreamHandlerFactory方法只能set一个factory

    public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) {
        synchronized (streamHandlerLock) {
            if (factory != null) {
                throw new Error("factory already defined");
            }
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkSetFactory();
            }
            handlers.clear();
            factory = fac;
        }
    }

为了能够支持,网上搜了一下(https://stackoverflow.com/questions/41696088/register-custom-urlstreamhandler-in-spring-web-application-tomcat),可以使用反射的方式将原有的factory设置成null,然后再用装饰器模式设置一个新的factory,用于兼容新的url类型,示例如下:

/**
     * 如果已经存在factory,则加一个装饰器,将原来的factory和用来读取hdfs的factory都封装进去,按需使用
     *
     * @param fsUrlStreamHandlerFactory
     * @throws Exception
     */
    private static void registerFactory(final FsUrlStreamHandlerFactory fsUrlStreamHandlerFactory)
            throws Exception {
        log.info("registerFactory : " + fsUrlStreamHandlerFactory.getClass().getName());
        final Field factoryField = URL.class.getDeclaredField("factory");
        factoryField.setAccessible(true);
        final Field lockField = URL.class.getDeclaredField("streamHandlerLock");
        lockField.setAccessible(true);
        // use same lock as in java.net.URL.setURLStreamHandlerFactory
        synchronized (lockField.get(null)) {
            final URLStreamHandlerFactory originalUrlStreamHandlerFactory = (URLStreamHandlerFactory) factoryField.get(null);
            // Reset the value to prevent Error due to a factory already defined
            factoryField.set(null, null);
            URL.setURLStreamHandlerFactory(protocol -> {
                if (protocol.equals("hdfs")) {
                    return fsUrlStreamHandlerFactory.createURLStreamHandler(protocol);
                } else {
                    return originalUrlStreamHandlerFactory.createURLStreamHandler(protocol);
                }
            });
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值