让我从例子开始。假设有工厂接口和Customer类:
public interface CustomerFactory(){
Customer create();
}
public class Customer(){
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
假设我有 CustmerProject maven项目需要 CustomerFactory 。我想用 CustomerFactory 实现(每个cource项目一个实现)创建几个maven项目,但我不希望 CustmerProject 将依赖于所有这些实现项目。我想创建一个 CustomerFactoryIntefaceProject , CustmerProject 将依赖于它,并将 CustomerFactoryImplementationProject 中的一个作为CustomerFactoryIntefaceProject。我知道这是可能的,但我在实践中如何做到这一点?
P.S。如果问题不明确,请问我。
答案 0 :(得分:1)
您可以参数化artifactId或CustomerFactoryImplementationProject的版本,并使用maven配置文件在构建期间选择实现。
假设你有以下文物:
因此,在客户项目的pom.xml中,您将需要:
<dependency>
<groupId>base</groupId>
<artifactId>${customer.factory.artifact}</artifact>
<version>123</version>
</dependency>
....
<profiles>
<profile>
<id>customerFactory1</id>
<properties>
<customer.factory.artifact>customer-factory-1</customer.factory.artifact>
</properties>
</profile>
<profile>
<id>customerFactory2</id>
<properties>
<customer.factory.artifact>customer-factory-2</customer.factory.artifact>
</properties>
</profile>
</profiles>
现在只需在构建期间选择配置文件,如下所示:
mvn -P customerFactory2 install
...或者实际上您可以直接分析依赖关系块:
<profiles>
<profile>
<id>customerFactory1</id>
<dependencies>
<dependency>
<groupId>base</groupId>
<artifactId>customer-factory-1</artifact>
<version>123</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>customerFactory2</id>
<dependencies>
<dependency>
<groupId>base</groupId>
<artifactId>customer-factory-2</artifact>
<version>123</version>
</dependency>
</dependencies>
</profile>
</profiles>
答案 1 :(得分:1)
我找到的解决方案非常类似于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);
这是“inteface”API。
对于“实现”API slf4j-api 项目包含带有3个存根类的impl包: StaticLoggerBinder , StaticMarkerBinder 和 StaticMDCBinder < / em> LoggerFactory 类中使用哪些方法,但在 slf4j-api 项目中,它们会抛出UnsupportedException。
现在让我们看看依赖于 slf4j-api 的 slf4j-jdk14 项目,并且只包含带有前面提到的3个类的impl包: StaticLoggerBinder , StaticMarkerBinder 和 StaticMDCBinder ;和 JDK14LoggerAdapter , JDK14LoggerFactory ,它们从 slf4j-api 实现 LocationAwareLogger 和 ILoggerFactory 。但它们不是存根,它们有一个真实的代码,例如 StaticLoggerBinder 返回 JDK14LoggerFactory ,它产生 JDK14LoggerAdapter 。
现在让我们来看看Maven魔术出现的地方。回想一下,“inteface”和“implementation”项目都有相同的类 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 继续构建并将实际的“实现”类放入“而不是”存根。