Question

There are multiple classes annotated with @Configuration and I want to decide in a top-level config component which one to register in the context.

@Configuration
public class FileSystemDataStoreConfiguration {
  public @Bean DataStore getDataStore() {
    return new FileSystemDataStore(withSomeConfigProperties);
  }
}

@Configuration
public class DatabaseDataStoreConfiguration {
  public @Bean DataStore getDataStore() {
    return new DatabaseDataStore(withSomeConfigProperties);
  }
}

@Configuration
public class DataStoreConfiguration {

  // Some arbitrary logic to decide whether I want to load
  // FileSystem or Database configuration.

}

I understand that I can use @Profile to select among multiple configuration classes. However, I already use profiles to distinguish between environments. The selection of the configuration classes is indepedent from the environment.

How can I select at runtime which configuration class to load?

Can I have multiple active profiles like "Production, WithDatabase"?

If so, how can I add a profile based on a property?

Was it helpful?

Solution

Spring, so there are lots of ways to do things!

If you stay all annotations, you can use the @ActiveProfiles annotation so enable the overall set of profiles you want:

@ActiveProfiles(profiles = ProfileDefinitions.MY_ENABLED_PROFILE)
@ContextConfiguration(as usual from here...)

You see the "profiles" allows many profiles to be set. You don't need to store the profiles as constants either, but you may find that helpful:

public class ProfileDefinitions {

    public static final String MY_ENABLED_PROFILE = "some-profile-enabled";

    // you can even make profiles derived from others:
    public static final String ACTIVE_WHEN_MY_IS_NOT = "!" + MY_ENABLED_PROFILE;
}

Using all of the above, you can selectively enable various configurations based upon the dynamic setting of the Profiles:

@Profile(ProfileDefinitions.MY_ENABLED_PROFILE)
@Configuration
@Import({these will only be imported if the profile is active!})
public class DatabaseDataStoreConfiguration {
}

@Profile(ProfileDefinitions.ACTIVE_WHEN_MY_IS_NOT)
@Configuration
@Import({if any are necessary})
public class DataStoreConfiguration {
}

OTHER TIPS

If you are using Spring 4, you could use the new @Conditional annotation functionality (which is actually the backend used to implement @Profile)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top