gpt4 book ai didi

java - 有没有办法注入(inject)一个依赖项,该依赖项将根据注入(inject)的位置(使用 Spring 引导)使用特定的 bean?

转载 作者:行者123 更新时间:2023-12-05 07:01:07 25 4
gpt4 key购买 nike

我有一个服务(我们称它为 TaskExecutorService),它需要一个依赖项 TaskService。我习惯于通过构造函数注入(inject)依赖,所以我使用了以下代码:

@Service
class TaskExecutorService {
private final TaskService taskService;

public TaskExecutorService(TaskService taskService) {
this.taskService = taskService;
}

void function1() {...}
void function2() {...}
}

TaskService 有一个依赖项TaskRetrieverService,它是一个接口(interface),由多个用@Service 注释的“检索器”实现。

@Service
class TaskService {
private final TaskRetrieverService taskRetrieverService;

public TaskService(TaskRetrieverService taskRetrieverService) {
this.taskRetrieverService = taskRetrieverService;
}
}

TaskExecutorService 中注入(inject) TaskService 并选择使用哪个检索器的最佳方法是什么?此外,我的实际用例是根据 TaskExecutorService 中的函数(function1function2),我希望能够使用“猎犬”或其他。

我认为我可以使用其构造函数直接在方法中实例化 TaskService,但我希望有一个最好的方法来执行此操作。

最佳答案

我同意这是某种反模式,因为您正在连接 @Bean,但我需要这样做几次并且没有义务对接口(interface)实现进行硬编码。

答案是,您可以在使用 @Bean(name = "customName") 在 Spring Config 中声明 bean 时为其命名。这样,您就可以选择要使用的接口(interface)实现

对于以下示例(根据您的情况),我有一个名为 Dependency.java 的接口(interface)依赖项。对于这个例子,让我们保持简单,它只有一个方法 print(),它会根据我们在运行时使用的实现打印一些东西。

public interface Dependency {
void print();
}

对于这种依赖,我有两种可能的实现方式。它们是 Child1Child2

这是Child1.java

public class Child1 implements Dependency {
@Override
public void print() {
System.out.println("I'm Child1!");
}
}

这是Child2.java

public class Child2 implements Dependency {
@Override
public void print() {
System.out.println("I'm Child2!");
}
}

如您所见,它们仅从我们的 Dependency.java 中实现,不做任何其他事情。他们实现该方法,该方法打印一条语句以区分正在运行时实现的方法。

然后我有一个名为 SpringConfig.java

的 Spring Config 类
@Configuration
@ComponentScan("you.packages.go.here.for.discovery.**.*")
public class SpringConfig {

@Bean(name = "myBean1")
public Dependency dependency() {
return new Child1();
}

@Bean(name = "myBean2")
public Dependency dependency2() {
return new Child2();
}

}

在这里,我声明了 2 个 bean,每个 bean 都有一个唯一名称。对于此示例,第一个实现 (Child1) 将称为 myBean1,第二个实现 (Child2) 将称为 myBean2.

然后我有了 @Service 类,它将使用这两个 @Beans 之一。 我使用 Spring 在此处连接 Context,而不是使用 new Child1() 进行硬连接。这样我就可以根据逻辑选择我想选择的。

@Service
public class MyService implements ApplicationContextAware {

private ApplicationContext context;

public void useDependency() {
Dependency dependency = (Dependency) context.getBean("myBean2");
dependency.print();
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}

上下文由 implements ApplicationContextAware 实现。这将添加保存 ApplicationContextsetApplicationContext() 方法。有了这个上下文后,您只需选择要在上一行中使用哪个接口(interface)实现

Dependency dependency = (Dependency) context.getBean("myBean2");

如果您将 myBean2 更改为 myBean1 (或您在 SpringConfig 的参数 @Bean 中设置的任何其他名称(name = "something") 你会将运行时实现更改为那个 @Bean)。

我实现了 @Bean myBean2,所以正如预期的那样,这将打印

"I'm Child2!"

关于java - 有没有办法注入(inject)一个依赖项,该依赖项将根据注入(inject)的位置(使用 Spring 引导)使用特定的 bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63941645/

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