Search code examples
javaspringspring-bean

Spring choose bean implementation at runtime


I'm using Spring Beans with annotations and I need to choose different implementation at runtime.

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

For example for windows's platform I need MyServiceWin extending MyService, for linux platform I need MyServiceLnx extending MyService.

For now I know only one horrible solution:

@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();
   }
}

Please consider that I'm using annotation only and not XML config.


Solution

  • 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;
    
        // ... 
    }