gpt4 book ai didi

java - Spring中如何让用户决定接口(interface)使用哪种实现?

转载 作者:行者123 更新时间:2023-12-02 13:36:55 25 4
gpt4 key购买 nike

我正在开发一个 SDK,它将用于创建用于批处理的其他应用程序。有 core-a-api 模块,它包含接口(interface) Client

public interface Client {
void send();

}

core-a-impl,其中包含Client接口(interface)的几个实现 - HttpClientTcpClient。< br/>此外,还有一个核心模块core-b-impl,它使用Client接口(interface)的特定实例。

public class SendingTasklet implements Tasklet {
@Autowired
private Client client

public void process() {
client.send();
}

}
应创建什么实例(HttpClientSftpClient)应由使用 SDK 创建应用程序的用户决定。他还需要能够为Client创建自己的实现并在SendingTasklet中使用它。来自核心依赖项的用户只能看到来自 -api 模块的接口(interface)。对于依赖注入(inject),我使用 Spring。特定模块的所有 bean 都是在每个模块中单独创建的。用户创建的bean是在用户的配置类中创建的

@Configuration
public class UsersApplicationConf {

@Bean
public Client client {
return new UsersClient();
}

}

问题是,在不暴露用户应用程序的 -impl 模块详细信息的情况下,他应该能够决定可以从核心提供的实现中使用哪些客户端实现,或者他应该能够通过它自己的之一。

第一个想法是在注入(inject)SendingTasklet时使用限定符,但是随后您需要为SendingTasklet中的每个实现创建一个单独的实例变量,这不是很好因为如果 Client 接口(interface)有更多实现,则也需要更改 SendingTasklet。还有一个问题,即用户应该以某种方式决定使用哪个实现仍然存在。

我所做的,我为客户的应用程序公开了core-a-impl。因此,在他的配置中,他可以决定为 Client 接口(interface)创建什么实例。

@Configuration
public class UsersApplicationConf {

@Bean
public Client client {
return new HttpClient();
}

}

但这也不是很聪明,我在想还有其他方法可以解决这个问题吗?

最佳答案

您可以使用策略或工厂模式,如上所述 here但我个人会选择 JSR 330,你可以找到一个例子 here ,下面是 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";
}
}

Edit: I didnt test the code but I have used javax.inject.Qualifier with CDI if this code doesnt work let me know I will update with correct combination and imports

关于java - Spring中如何让用户决定接口(interface)使用哪种实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42943145/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com