我找到了与 Macias 的帖子非常相似的解决方案,但来自真实代码。
主要思想是将存根类放入“接口”项目中,添加将在流程类阶段删除存根类的插件,使“实现”项目依赖于“接口”并使用具有相同包和类的真实代码创建类命名为存根。
我们以 slf4j 项目为例,您可以从http://www.slf4j.org/download.html下载源代码
主要项目是slf4j-api,包含接口:Logger、LocationAwareLogger(扩展Logger)、ILoggerFactory等,还包含LoggerFactory类(和几个 Utility 类),在创建 logger 时使用,例如:
private static final Logger logger = LoggerFactory.getLogger(SomeClass.class);
这是“接口”API。
对于“实现”API ,slf4j-api项目包含具有 3 个存根类的 impl 包:StaticLoggerBinder、StaticMarkerBinder和StaticMDCBinder,这些方法在LoggerFactory类中使用,但在slf4j-api项目中它们抛出 UnsupportedException。
现在让我们看一下slf4j-jdk14项目,它依赖于slf4j-api并且只包含 impl 包和前面提到的 3 个类:StaticLoggerBinder、StaticMarkerBinder和StaticMDCBinder;和JDK14LoggerAdapter,JDK14LoggerFactory从slf4j-api实现LocationAwareLogger和ILoggerFactory。但它们不是存根,它们有一个真实的代码,例如StaticLoggerBinder返回产生JDK14LoggerAdapter的JDK14LoggerFactory。
现在让我们看看 Maven 魔法发挥作用的地方。回想一下,“接口”和“实现”项目都具有相同的类StaticLoggerBinder、StaticMarkerBinder和StaticMDCBinder。查看slf4j-api pom.xml并找到构建标签:
<project>
...
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<tasks>
<echo>Removing slf4j-api's dummy StaticLoggerBinder and StaticMarkerBinder</echo>
<delete dir="target/classes/org/slf4j/impl"/>
</tasks>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
因为slf4j-jdk14依赖于slf4j-api,所以首先构建 slf4j-api,然后插件删除存根,然后继续构建slf4j-jdk14并放置实际的“实现”类“而不是”存根。