简体   繁体   English

Java如何初始化JAXB / JAX-WS / etc实现?

[英]How does Java initialize the JAXB/JAX-WS/etc implementation?

I'm just digging around a bit trying to understand how Java can have standard reference implementations included in the JRE (eg JAXB/JAX-WS in JRE6), while still allowing 3rd-party implementations to override that (eg CXF). 我只是想了解一下Java如何在JRE中包含标准参考实现(例如JRE6中的JAXB / JAX-WS),同时仍然允许第三方实现覆盖它(例如CXF)。

I've gotten to the place that I found the javax.xml.ws.spi.FactoryFinder.find() method which either locates the class specified in META-INF/services/java.xml.ws.spi.Provider or com.sun.xml.internal.ws.spi.ProviderImpl (for the JAX-WS case) and creates an instance of that. 我找到了找到javax.xml.ws.spi.FactoryFinder.find()方法的地方,该方法可以找到META-INF / services / java.xml.ws.spi.Provider或com中指定的类。 sun.xml.internal.ws.spi.ProviderImpl(对于JAX-WS案例)并创建一个实例。

What I can't find is how/where/at which stage the JRE calls that FactoryFinder.find() method. 我找不到的是JRE调用FactoryFinder.find()方法的时间/位置/在哪个阶段。

Can anybody enlighten me? 任何人都可以开导我吗?

[edit] I've found the answer but am not allowed to post it myself for another 3 hours... [编辑]我找到了答案,但我不允许自己发布另外3个小时......

Figured out the complete logic. 找出完整的逻辑。 Actually nothing happens on JVM startup. 实际上JVM启动时没有任何反应。 It's all based on lazy loading, eg the real JAX-WS/whatever provider is only loaded/instantiated the first time it's needed. 它全部基于延迟加载,例如真正的JAX-WS /任何提供程序仅在第一次需要时加载/实例化。

In the case of loading the JAX-WS implementation: 在加载JAX-WS实现的情况下:

Assume we want to call a web service, using code like: 假设我们想要使用以下代码调用 Web服务:

MyService     service = new MyService_Service();
MyServiceSoap port    = service.getMyServiceSoap();

port.mymethod(); 

then the following happens to initialize the JAX-WS implementation: 然后,以下事件初始化JAX-WS实现:

  • Any JAX-WS webservice extends javax.xml.ws.Service, so MyService_Service extends Service 任何JAX-WS Web服务都扩展了javax.xml.ws.Service,因此MyService_Service扩展了Service
  • When you create an instance of your web service, its superclass (javax.xml.ws.Service) is also initialized (constructor) 当您创建Web服务的实例时,其超类(javax.xml.ws.Service)也会被初始化(构造函数)
  • The constructor for "Service" calls javax.xml.ws.spi.Provider.provider(), which is a static method that uses javax.xml.ws.spi.FactoryFinder.find() to find and instantiate the implementation as configured. “Service”的构造函数调用javax.xml.ws.spi.Provider.provider(),这是一个静态方法,它使用javax.xml.ws.spi.FactoryFinder.find()来查找并实例化已配置的实现。

Assume we want to publish a web service using code like: 假设我们想要使用以下代码发布 Web服务:

@WebService(endpointInterface = "my.package.MyService")
public class MyServiceImp implements MyService {
    ...
}

MyServiceImp      service  = new MyServiceImp();
InetSocketAddress addr     = new InetSocketAddress(8080);
Executor          executor = Executors.newFixedThreadPool(16);
HttpServer        server   = new HttpServer(addr);
server.setExecutor(executor);

HttpContext       context  = server.createContext("/MyService");
Endpoint          endpoint = Endpoint.create(service);
endpoint.publish(context);
server.start();

then the following happens to initialize the JAX-WS implementation: 然后,以下事件初始化JAX-WS实现:

  • Endpoint.create() runs Provider.provider().createEndpoint() Endpoint.create()运行Provider.provider()。createEndpoint()
  • Provider.provider() is a static method that uses javax.xml.ws.spi.FactoryFinder.find() to find and instantiate the implementation as configured. Provider.provider()是一个静态方法,它使用javax.xml.ws.spi.FactoryFinder.find()来查找和实例化已配置的实现。

The following links helped me understand this: 以下链接帮助我理解了这一点:

You can change the default behavior using system property javax.xml.bind.context.factory . 您可以使用系统属性javax.xml.bind.context.factory更改默认行为。 Its value should be the fully qualified class name of the factory. 它的值应该是工厂的完全限定类名。

The default value of this property is com.sun.xml.internal.bind.v2.ContextFactory . 此属性的默认值为com.sun.xml.internal.bind.v2.ContextFactory This factory is not required to implement any specific interface by it must implement method createContext(String, ClassLoader, Map) 这个工厂不需要实现任何特定的接口,它必须实现方法createContext(String, ClassLoader, Map)

There are a few mechanisms which control which implementation you use. 有一些机制可以控制您使用的实现。 each jre/jdk has a built in "default" implementation hardcoded into the init code. 每个jre / jdk都有一个内置的“默认”实现,硬编码到init代码中。 There are also some system properties you can use to specify a specific implementation (as @AlexR mentioned). 您还可以使用一些系统属性来指定特定的实现(如提到的@AlexR)。 however, that is not the standard mechanism for specifying a different implementation. 但是,这不是指定不同实现的标准机制。 most alternate implementations include a special file in their META-INF directory (within the jar) which indicate to the jre/jdk that they should be used instead of the default implementation (this works without setting any system properties, you just drop the jars into the classpath). 大多数替代实现在其META-INF目录(在jar中)中包含一个特殊文件,它指示jre / jdk应该使用它们而不是默认实现(这可以在不设置任何系统属性的情况下工作,你只需将jar放入classpath)。 these special files are found by ServiceLoader utility and enable the alternate implementation to be automatically loaded. ServiceLoader实用程序可以找到这些特殊文件,并可以自动加载备用实现。

I found that a working JAXB sample fails after putting a weblogicfullclient.jar onto the classpath, because the jar contains a META-INF/services/javax.xml.bind.JAXBContext but not the implementation. 我发现在将一个weblogicfullclient.jar放到类路径后,一个正在运行的JAXB示例失败了,因为jar包含一个META-INF / services / javax.xml.bind.JAXBContext但不包含实现。 Unfortunately, one cannot tell JAXB to "just use PLATFORM_DEFAULT_FACTORY_CLASS", you have to put it on a System property (-Djavax.xml.bind.JAXBContext=com.sun.xml.internal.bind.v2.ContextFactory for 1.6 and -Djavax.xml.bind.context.factory=.. for 1.7), the javax.xml.bind.ContextFinder.find(String, String, ClassLoader, Map) implementations differ for 1.6 and 1.7 不幸的是,人们不能告诉JAXB“只使用PLATFORM_DEFAULT_FACTORY_CLASS”,你必须把它放在一个System属性上(-Djavax.xml.bind.JAXBContext = com.sun.xml.internal.bind.v2.ContextFactory for 1.6 and -Djavax .xml.bind.context.factory = ..对于1.7),javax.xml.bind.ContextFinder.find(String,String,ClassLoader,Map)实现在1.6和1.7上有所不同

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

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