Spring在运行时选择bean实现

新手上路,请多包涵

我正在使用带注释的 Spring Beans,我需要在运行时选择不同的实现。

 @Service
public class MyService {
   public void test(){...}
}

例如,对于 Windows 平台,我需要 MyServiceWin extending MyService ,对于 Linux 平台,我需要 MyServiceLnx extending MyService

现在我只知道一个可怕的解决方案:

 @Service
public class MyService {

    private MyService impl;

   @PostInit
   public void init(){
        if(windows) impl=new MyServiceWin();
        else impl=new MyServiceLnx();
   }

   public void test(){
        impl.test();
   }
}

请考虑我只使用注释而不是 XML 配置。

原文由 Tobia 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 360
2 个回答

您可以将 bean 注入移动到配置中,如下所示:

 @Configuration
public class AppConfig {

    @Bean
    public MyService getMyService() {
        if(windows) return new MyServiceWin();
        else return new MyServiceLnx();
    }
}

Alternatively, you may use profiles windows and linux , then annotate your service implementations with the @Profile annotation, like @Profile("linux") or @Profile("windows") ,并为您的应用程序提供其中一个配置文件。

原文由 Stanislav 发布,翻译遵循 CC BY-SA 3.0 许可协议

1.实现自定义 Condition

 public class LinuxCondition implements Condition {
  @Override
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    return context.getEnvironment().getProperty("os.name").contains("Linux");  }
}

Windows 相同。

2.在你的 Configuration 类中使用 @Conditional

 @Configuration
public class MyConfiguration {
   @Bean
   @Conditional(LinuxCondition.class)
   public MyService getMyLinuxService() {
      return new LinuxService();
   }

   @Bean
   @Conditional(WindowsCondition.class)
   public MyService getMyWindowsService() {
      return new WindowsService();
   }
}

3.像往常一样使用 @Autowired

 @Service
public class SomeOtherServiceUsingMyService {

    @Autowired
    private MyService impl;

    // ...
}

原文由 nobeh 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题