我有一个接口和多个实现.我正在类中自动连接接口以供使用.我需要在运行时 Select 不同的实现.

public class Util {
  public void getClient();
}

启动位置

public class UtilOne implements Util {
  public void getClient() {...}
}

public class UtilTwo implements Util {
  public void getClient() {...}
}

@Configuration
public class AppConfig {
  
  @Autowired
  @Bean
  @Primary
  public Util utilOne() {
    return new UtilOne();
  }

  @Autowired
  @Bean
  public Util utilTwo() {
    return new UtilTwo();
  }

}
@Component
public class DemoService {

  @Autowired
  private Util util;
}

由于某些原因,如果我们无法在UtilOne中获取客户端,我想在不重新启动应用程序的情况下切换到UtilTwo.我想将DemoService中的Util对象更改为UtilTwo对象.

推荐答案

它不是这样工作的——如果你有一个特定的Util实现,比如说,连接到类SampleClass(它是一个单例),你不能在不重新启动应用程序上下文的情况下,将Util的实现真正更改为不同的实现.

因此,我建议另一种 Select ,而不是走这条路.您说,在运行时判断的特定条件下,您希望切换实现.这是什么情况?是否可以提取该条件决策逻辑?

如果是这样,您可以自动连接一个特殊的DynamicUtil,它将保存对所有util的引用,并根据条件调用所需的util:

// represents all possible business 'runtime' outcomes
enum ConditionOutcome {
   A, B, C 
}
interface ConditionEvaluator {
   ConditionOutcome evaluate(); // when called in runtime will evaluate a condition that currently exists in the system
}

interface Util {
   void foo();
   ConditionOutcome relevantOfOutcome();
}

class Utill1Impl implements Util {
   public void foo() {...}
   public ConditionOutcome relevantOfOutcome() {return ConditionOutcome.A;}
}
class Utill2Impl implements Util {
   public void foo() {...}
   public ConditionOutcome relevantOfOutcome() {return ConditionOutcome.B;}
}
class Utill3Impl implements Util {
   public void foo() {...}
   public ConditionOutcome relevantOfOutcome() {return ConditionOutcome.C;}
}

class DynamicUtil {
   private final Map<ConditionOutcome, Util> possibleImpls;
   private final ConditionEvaluator evaluator;

   public class DynamicUtil(List<Util> allImplementations, ConditionEvaluator evaluator) {
      // create a map by calling the 'relevantOfOutcome' per util impl in a loop
    this.evaluator = evaluator;
   }
   
   public void foo() {
      ConditionOutcome key = evaluator.evaluate();
      // pick the relevant implementation based on evaluated key
      possibleImpls.get(key).foo();
   }
}

现在有了这样的设计,您可以动态地添加新的可能结果(以及应该实现它们的UTIL).不过,系统中的类将必须自动连接DynamicUtil,因此有效地引入了一个额外的间接级别,但将获得灵活性

class SampleClass { // a business class that will need to work with util capable of being changed during the runtime 
   @Autowired
   private DynamicUtil util;
   ... 
}

Java相关问答推荐

是否保证在事务性块的末尾标记违反约束?

具有多种令牌类型和段的复杂Java 17正则表达式

将带有js文件的 bootstrap 程序导入maven项目时出错

如何正确创建序列图?

Java-动态绑定-问题-了解

基于接口的投影、原生查询和枚举

从映射列表中检索所有键

插入中的JOOQ序列,设置为VS值

具有最大共同前景像素的图像平移优化算法

Java中的发布/订阅-Long Live和Short Live Publisher,哪种方法是正确的?

使用@ExceptionHandler的GlobalExceptionHandler还是来自服务器的REST应答的ResponseEntity?

为什么我的登录终结点不能被任何请求访问?

Java中的一个错误';s stdlib SocksSocketImpl?

AspectJ编织外部依赖代码,重新打包jar并强制依赖用户使用它

java构造函数中的冻结操作何时发生?

我可以使用一个 PoolingNHttpClientConnectionManager 运行多个 HttpAsyncClient 吗?

JavaFX 不嵌入谷歌 map html

Sonarlint 警告我可能出现 NullPointerException,但在我看来,我做了必要的事情来防止它发生?

将 JSF 2.3 应用程序部署到 Tomcat 9.0.80 时出现异常

关于龙目岛项目的future