运行时的弹簧选择 Bean 实现

2022-08-31 14:15:17

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

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

例如,对于Windows的平台,我需要,对于Linux平台,我需要。MyServiceWin extending MyServiceMyServiceLnx 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配置。


答案 1

1. 实现自定义条件

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

与 相同。Windows

2. 在课堂上使用@ConditionalConfiguration

@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;

    // ... 
}

答案 2

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

@Configuration
public class AppConfig {

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

或者,您可以使用配置文件 和 ,然后使用注释(如 or )对服务实现进行批注,并为应用程序提供其中一个配置文件。windowslinux@Profile@Profile("linux")@Profile("windows")


推荐