我不明白java如何知道任何规范的实现..
例如,我有一个带有 JSF 的 Spring 应用程序,如果我将 Mojarra jar 放在类路径上,应用程序就可以工作,但我什么也没做,只是将它添加到类路径中,所有这些都没有配置
如果我取出 Mojarra jar,那么我的应用程序将无法运行。
甚至,如何在没有任何变化的情况下区分 Mojarra 或 MyFaces?
我只想知道 Java 是如何找到实现的,而不是为什么如果我拿出罐子它就不起作用;)
我不明白java如何知道任何规范的实现..
例如,我有一个带有 JSF 的 Spring 应用程序,如果我将 Mojarra jar 放在类路径上,应用程序就可以工作,但我什么也没做,只是将它添加到类路径中,所有这些都没有配置
如果我取出 Mojarra jar,那么我的应用程序将无法运行。
甚至,如何在没有任何变化的情况下区分 Mojarra 或 MyFaces?
我只想知道 Java 是如何找到实现的,而不是为什么如果我拿出罐子它就不起作用;)
通常 Java 规范类分为两部分:
上面的一个例子是 JDBC:javax.sql.*
类由 提供sun/oracle
,但实现是在每个数据库供应商提供的 JDBC 驱动程序中完成的。在这种情况下,需要某种配置才能将 API“映射”到其实现,因为您API
只使用类。
你的例子JSF
有点不同,两者都Mojarra
包含MyFaces
包中的API
类javax.faces.*
,基本上有不同的类具有相同的名称。所以不需要配置,两个库中的类具有相同的名称,并且在需要时由类加载器从类路径上的 jarMojarra
或MyFaces
jar 加载。
我看过 mojarra jar(JSF 参考实现),我发现它使用了服务加载器 API,因为它放置了 javax.servlet.ServletContainerInitializer、javax.enterprise.inject.spi.Extension 和 com.sun.faces.spi javax.faces-2.2.0.jar 中 /META-INF/services 文件夹中的 .injectionprovider。
这就是 java 区分实现和另一个(mojarra 或 myfaces)的方式。
我找到了 JSF 的 MyFaces 和 Mojarra 实现。我已经意识到两者都具有相同的包结构,因此这意味着它们都符合 JSF 规范。换句话说,将哪个实现 jar 提供给类路径类路径加载器将处理它。
这完全是关于 JVM 的 Java 类加载器机制。您可以在 Java 类加载器中找到详细讨论
这是 JSF 实现包结构的图片。