繁体   English   中英

用反射替换java.net.URL URLStreamHandlerFactory是一个好主意吗?

[英]Is it a good idea to replace java.net.URL URLStreamHandlerFactory using reflection?

在Java中,我们可以通过至少两种方式注册自定义协议处理程序:

  1. 通过设置系统属性“ java.protocol.handler.pkgs”
  2. 使用URL.setURLStreamHandlerFactory

有关更多详细信息,请检查http://accu.org/index.php/journals/1434

我不能选择第一个选项,因为我必须向服务器(tomcat)类路径中添加很多jar文件,以使处理程序实现对于引导类加载器可见。 而且,需要一些初始化,这必须在应用程序上下文中完成。

第二个选项的问题是工厂只能注册一次(请检查java.net.URL#setURLStreamHandlerFactory),不幸的是,它是由Tomcat完成的。

我能做的是创建一个装饰工厂,该工厂将通过我的协议处理程序扩展现有工厂。 与使用relfection相比,将静态字段URL#factory设置为null,然后使用URL#setURLStreamHandlerFactory以标准方式注册(再次?)我的“ decoratorFactory”。 我只是想知道在这里使用反射是否是个好主意...? 安全性如何?

我想做这样的事情:

try {
        Field factoryField = URL.class.getDeclaredField("factory");
        factoryField.setAccessible(true);
        //  get current factory
        Object currentFactory = factoryField.get(null);
        //  define a decorator factory
        MyFactoryDecorator mfd = new MyFactoryDecorator(currentFactory);
        //  set the factory to null and register MyFactoryDecorator using URL#setURLStreamHandlerFactory.
        factoryField.set(null, null);
        URL.setURLStreamHandlerFactory(mfd);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

Idk是否行得通,但是如果您创建一个实际上不包含实现的新URLStreamHandlerFactory怎么办? 它只是坐在那里,然后在通过应用上下文查找调用时在运行时实例化真正的实现。 然后,从理论上讲,您可以在开始时通过system属性实例化此新代理处理程序,但也可以在实际调用它时使用所需的代理处理程序。

更新:

实际上,我认为您上面的链接提到了此策略:

另一种方法是使用工厂注册,但提供一个工厂类,该工厂类本身支持使用不同名称的多个不同流处理程序的注册。

这种方法支持使用java.net.URL类的代码,但是它确实需要为每个协议进行注册调用,因此,在应用程序可以使用新URL之前,需要对其进行更改。 但是,由于工厂是由用户代码类加载器而不是URL类的类加载器加载的,因此该方法解决了以上在多类加载器中讨论的问题。

我对您正在做的所有事情以及注册的工作方式并不十分熟悉,因此根据您正在做的事情,这可能会变得或多或少复杂。 如果您甚至不需要额外的注册,则为idk,但这听起来可能可以解决.jar / app上下文问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM