Spring choose bean implementation at runtime

You can move the bean injection into the configuration, as:

@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"), and provide one of this profiles for your application.


1. Implement a custom Condition

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

Same for Windows.

2. Use @Conditional in your Configuration class

@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. Use @Autowired as usual

@Service
public class SomeOtherServiceUsingMyService {

    @Autowired    
    private MyService impl;

    // ... 
}