Java如何找到规范实现?

4
我不明白java如何知道任何规范的实现方式。
例如,我有一个使用JSF的Spring应用程序,如果我将Mojarra jar放在类路径中,则该应用程序可以工作,但我什么都没有做,只是将它添加到类路径中,无需配置即可。
如果我删除Mojarra jar,那么我的应用程序就无法工作。
甚至,它如何区分Mojarra或MyFaces而不进行任何更改?
我只想知道Java如何找到实现,而不是为什么如果我拿出jar文件,它就不能工作;)

1
Java只需要查找类名就能加载类。它会检查其构建路径并遍历所有的jar文件和其他库,直到找到所要寻找的类文件的实现。 - Mahesh Guruswamy
3
@MaheshGuruswamy可以发表一个回答吗? - Luiggi Mendoza
@LuiggiMendoza,我已经发布了一个答案。这是给OP的一个提示,让他查找Java中的类加载及其工作原理。 - Mahesh Guruswamy
@MaheshGuruswamy,我没有看到你作为作者的回答,只有一条评论。 - Luiggi Mendoza
3个回答

2
通常,Java规范类分为两部分:
1. API部分(jar),包含主要由规范人员提供的接口。 2. 实现部分(jar),包含这些接口的实现。
例如JDBC:javax.sql.*类由sun/oracle提供,但是其实现是由每个数据库供应商提供的JDBC驱动程序完成。在这种情况下,需要一定的配置才能将API映射到其实现,因为您只使用API类。
JSF的示例与此略有不同,因为Mojarra和MyFaces都包含javax.faces.*包中的API类,基本上是具有相同名称的不同类。因此,无需配置,这些类在两个库中具有相同的名称,并且由类加载器从classpath上的Mojarra或MyFaces jar中加载时,它们会被自动加载。

谢谢@dcernahoschi,但我想知道如何执行“map”,因为如果我放置mojarra jar或myfaces jar,它们中的每一个都有不同的实现类名称,那么Java如何读取javax.jsf.Impl1或javax.jsf.other.Impl2??? - rvillablanca
也许我没有解释清楚:在Mojarra和MyFaces的情况下,这些类(虽然不同)具有相同的名称,无需进行映射。 - dcernahoschi

0

我已经找到了JSF的MyFaces和Mojarra实现。我已经意识到它们两个具有相同的包结构,这意味着它们都符合JSF规范。换句话说,无论哪个实现JAR包被放入类路径中,类加载器都将处理它。

这涉及到JVM的Java类加载机制。您可以在Java类加载器上找到详细的讨论。

这是两个JSF实现包结构的图片。

enter image description here


0

我看过mojarra jar(JSF参考实现),发现它使用了Service Loader API,因为它将javax.servlet.ServletContainerInitializer、javax.enterprise.inject.spi.Extension和com.sun.faces.spi.injectionprovider放置在javax.faces-2.2.0.jar的/META-INF/services文件夹中。

这就是Java区分实现(mojarra或myfaces)的方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接