Java 如何让用户决定在Spring中为接口使用哪个实现?
我正在开发一个SDK,它将用于创建用于批处理的其他应用程序。有一个core-a-api模块,用于保存客户端接口 公共接口客户端{ 无效发送; } 以及core-a-impl,它为客户端接口(HttpClient和TcpClient)提供了两个实现。 另外,还有一个核心模块core-b-impl,它使用客户机接口的特定实例。 } 应该创建哪个实例HttpClient或SftpClient应由使用SDK创建应用程序的用户决定。他还需要能够为客户端创建自己的实现,并在SendingTasklet中使用它。来自核心依赖项的用户只能看到来自-api模块的接口。对于依赖注入,我使用Spring。在每个模块中分别创建特定模块的所有bean。用户创建的bean是在用户的配置类中创建的 @配置 公共类UsersApplicationConf{ @豆子 公共客户端{ 返回新用户客户端; } } 问题是,在不公开用户应用程序的-impl模块详细信息的情况下,他应该能够决定从核心提供的实现中可以使用什么客户端实现,或者他应该能够通过自己的实现 第一个想法是在注入SendingAsklet时使用限定符,但随后需要为SendingAsklet中的每个实现创建一个单独的实例变量,这不是很好,因为如果客户端接口有更多实现,那么也需要更改SendingAsklet。还有一个问题,用户应该以某种方式决定使用哪个实现 我所做的是,为客户机的应用程序公开了core-a-impl。所以在他的配置中,他可以决定为客户机接口创建哪个实例 @配置 公共类UsersApplicationConf{ @豆子 公共客户端{ 返回新的HttpClient; } }Java 如何让用户决定在Spring中为接口使用哪个实现?,java,spring,Java,Spring,我正在开发一个SDK,它将用于创建用于批处理的其他应用程序。有一个core-a-api模块,用于保存客户端接口 公共接口客户端{ 无效发送; } 以及core-a-impl,它为客户端接口(HttpClient和TcpClient)提供了两个实现。 另外,还有一个核心模块core-b-impl,它使用客户机接口的特定实例。 } 应该创建哪个实例HttpClient或SftpClient应由使用SDK创建应用程序的用户决定。他还需要能够为客户端创建自己的实现,并在SendingTasklet中使
但这也不是很聪明,我在想还有其他方法可以解决这个问题吗?您可以使用前面提到的策略或工厂模式,但我个人会使用JSR 330,您可以在下面的spring示例代码块中找到一个示例:
package spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static spring.Spring.Platform;
@Configuration
@ComponentScan
public class Spring {
public static void main(String[] args) {
new AnnotationConfigApplicationContext(Spring.class);
}
@Autowired
@Platform(Platform.OperatingSystems.ANDROID)
private MarketPlace android;
@Autowired
@Platform(Platform.OperatingSystems.IOS)
private MarketPlace ios;
@PostConstruct
public void qualifyTheTweets() {
System.out.println("ios:" + this.ios);
System.out.println("android:" + this.android);
}
// the type has to be public!
@Target({ElementType.FIELD,
ElementType.METHOD,
ElementType.TYPE,
ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public static @interface Platform {
OperatingSystems value();
public static enum OperatingSystems {
IOS,
ANDROID
}
}
}
interface MarketPlace {
}
@Component
@Platform(Platform.OperatingSystems.IOS)
class AppleMarketPlace implements MarketPlace {
@Override
public String toString() {
return "apple";
}
}
@Component
@Platform(Platform.OperatingSystems.ANDROID)
class GoogleMarketPlace implements MarketPlace {
@Override
public String toString() {
return "android";
}
}
编辑:我没有测试代码,但我使用了javax.inject.Qualifier
使用CDI如果此代码不起作用,请告诉我我将使用更新
正确组合和导入
我认为,您可以实现一个条件自动连接bean。
package spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static spring.Spring.Platform;
@Configuration
@ComponentScan
public class Spring {
public static void main(String[] args) {
new AnnotationConfigApplicationContext(Spring.class);
}
@Autowired
@Platform(Platform.OperatingSystems.ANDROID)
private MarketPlace android;
@Autowired
@Platform(Platform.OperatingSystems.IOS)
private MarketPlace ios;
@PostConstruct
public void qualifyTheTweets() {
System.out.println("ios:" + this.ios);
System.out.println("android:" + this.android);
}
// the type has to be public!
@Target({ElementType.FIELD,
ElementType.METHOD,
ElementType.TYPE,
ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public static @interface Platform {
OperatingSystems value();
public static enum OperatingSystems {
IOS,
ANDROID
}
}
}
interface MarketPlace {
}
@Component
@Platform(Platform.OperatingSystems.IOS)
class AppleMarketPlace implements MarketPlace {
@Override
public String toString() {
return "apple";
}
}
@Component
@Platform(Platform.OperatingSystems.ANDROID)
class GoogleMarketPlace implements MarketPlace {
@Override
public String toString() {
return "android";
}
}