-1

Suppose you need to dynamically (at runtime) get an instance of a subtype of a given type.

How would you accomplish that using Spring IoC?

Diego Shevek
  • 486
  • 3
  • 15
  • You can achieve the same in a more declarative way by using profiles – NilsH Apr 12 '13 at 18:10
  • You haven't asked a question. – Sotirios Delimanolis Apr 12 '13 at 18:12
  • @SotiriosDelimanolis I was to post a question, but when I came across the solution I decided to make it public, and then thought the option "Answer your own question" was the way to do it. blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/ "if you have a question that you already know the answer to if you’d like to document it in public so others (including yourself) can find it later it is OK to ask, and answer, your own question on a relevant Stack Exchange site. (...)it is not merely OK to ask and answer your own question, it is explicitly encouraged" – Diego Shevek Apr 12 '13 at 18:39
  • 1
    @DiegoAlcántara You can add your answer as an Answer, it'll be more obvious. – Sotirios Delimanolis Apr 12 '13 at 18:39
  • @NilsH Could you expand your comment as an answer? – Diego Shevek Apr 12 '13 at 18:49
  • I have added an answer, @DiegoAlcántara – NilsH Apr 12 '13 at 19:10

2 Answers2

1

You can also use @Profile to achieve similar functionality in a more declarative way.

@Configuration
@Profile("default")
public class TypeAConfig {
    @Bean
    public Type getType() {
        return new TypeA();
    }
}

@Configuration
@Profile("otherProfile")
public class TypeBConfig() {
    @Bean
    public Type getType() {
        return new TypeB();
    }
}

@Configuration
public class SysConfig {
    @Autowired
    Type type;       

    @Bean Type getType() {
        return type;
    }
}

You can then control which implementation to use by specifying the profiles that Spring should activate, e.g. with the spring.profiles.active system property. More information in the JavaDoc for Profile

NilsH
  • 13,705
  • 4
  • 41
  • 59
0

I've found the following is an easy way to do it.

@Component
public class SystemPreferences {
  public boolean useA() {...}
}

interface Type {....}

public class TypeA implements Type {
   @Autowired
   Other xyz;
}

public class TypeB implements Type {...}

@Configuration
public class SysConfig {
  @Autowired
  SystemPreferences sysPrefs;

  @Bean
  public Type getType() {
    if (sysPrefs.useA()) {
      //Even though we are using *new*, Spring will autowire A's xyz instance variable
      return new TypeA();
    } else {
      return new TypeB();
    }
  }
}
Diego Shevek
  • 486
  • 3
  • 15