在 Java 中,我们至少可以通过两种方式注册自定义协议处理程序:
- 通过设置系统属性'java.protocol.handler.pkgs'
- 使用 URL.setURLStreamHandlerFactory
更多详情请查看http://accu.org/index.php/journals/1434
我不能选择第一个选项,因为我必须向服务器(tomcat)类路径添加很多 jar 文件,以使处理程序实现对引导类加载器可见。此外,还需要一些初始化,这必须在应用程序上下文中完成。
第二个选项的问题是Factory只能注册一次(检查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();
}