简体   繁体   English

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

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

In Java we can register a custom protocol handler in at least two ways: 在Java中,我们可以通过至少两种方式注册自定义协议处理程序:

  1. by setting system property 'java.protocol.handler.pkgs' 通过设置系统属性“ java.protocol.handler.pkgs”
  2. using URL.setURLStreamHandlerFactory 使用URL.setURLStreamHandlerFactory

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

I can not go with the first option, as i would have to add a lot of jar files to the server (tomcat) classpath, to make the handler implementaion visible for bootstrap classloader. 我不能选择第一个选项,因为我必须向服务器(tomcat)类路径中添加很多jar文件,以使处理程序实现对于引导类加载器可见。 Moreover some initialization is needed, which has to be done in an application context. 而且,需要一些初始化,这必须在应用程序上下文中完成。

The problem with the second option is that the Factory can be registered only once (check java.net.URL#setURLStreamHandlerFactory), and unfortunately it is done by Tomcat. 第二个选项的问题是工厂只能注册一次(请检查java.net.URL#setURLStreamHandlerFactory),不幸的是,它是由Tomcat完成的。

What i can do is to create a decorator factory which will extend the existing one by my protocol handler. 我能做的是创建一个装饰工厂,该工厂将通过我的协议处理程序扩展现有工厂。 Than using relfection set the static field URL#factory to null and register (again?) my "decoratorFactory" in a standard way using URL#setURLStreamHandlerFactory. 与使用relfection相比,将静态字段URL#factory设置为null,然后使用URL#setURLStreamHandlerFactory以标准方式注册(再次?)我的“ decoratorFactory”。 I'm just wondering if it is a good idea to use the reflection here...? 我只是想知道在这里使用反射是否是个好主意...? How about the security? 安全性如何?

I would like to do something like that: 我想做这样的事情:

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 if this would work, but what if you create a new URLStreamHandlerFactory that doesn't actually contain the implementation? Idk是否行得通,但是如果您创建一个实际上不包含实现的新URLStreamHandlerFactory怎么办? It just sits there and then instantiates the real implementation at runtime when it is called via an app context lookup. 它只是坐在那里,然后在通过应用上下文查找调用时在运行时实例化真正的实现。 Then in theory you can instantiate this new proxy handler via the system property at the beginning, but also use the one you want when it is actually called. 然后,从理论上讲,您可以在开始时通过system属性实例化此新代理处理程序,但也可以在实际调用它时使用所需的代理处理程序。

UPDATE: 更新:

Actually, I think your link above mentions this strategy: 实际上,我认为您上面的链接提到了此策略:

Another approach is to use the factory registration, but to provide a factory class that itself supports registration of multiple different stream handlers using different names. 另一种方法是使用工厂注册,但提供一个工厂类,该工厂类本身支持使用不同名称的多个不同流处理程序的注册。

This approach supports code using the java.net.URL class but it does require a registration call for each protocol and so hence changes are needed to an application before it can make use of the new URLs. 这种方法支持使用java.net.URL类的代码,但是它确实需要为每个协议进行注册调用,因此,在应用程序可以使用新URL之前,需要对其进行更改。 However the approach gets around the problems discussed above with multiple class loaders since the factory is loaded by the user code class loader rather than by the class loader for the URL class. 但是,由于工厂是由用户代码类加载器而不是URL类的类加载器加载的,因此该方法解决了以上在多类加载器中讨论的问题。

I'm not super familiar with what all you're doing and how the registration works, so this could be more or less complicated depending on what you're doing. 我对您正在做的所有事情以及注册的工作方式并不十分熟悉,因此根据您正在做的事情,这可能会变得或多或少复杂。 Idk if you even need the extra registration or not, but it sounds like it might solve the .jar/app context problem. 如果您甚至不需要额外的注册,则为idk,但这听起来可能可以解决.jar / app上下文问题。

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

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