38

Is there any difference in usage of the annotations? Both the annotations allow to use multiple @Configuration classes to create an ApplicationContext. From their docs @ContextConfiguration seems to be more suitable for test configuration and comes from an artifact for tests (spring-test), however, I haven't found the actual difference.

Thank you for any thoughts!

pvpkiran
  • 25,582
  • 8
  • 87
  • 134
Dmitry Senkovich
  • 5,521
  • 8
  • 37
  • 74
  • 1
    `@ContextConfiguration` is only usable in tests in other code it doesn't do anything. `@Import` is useless on a test and will only be useful on `@Configuration` classes to import other configuration classes (with `@ImportResource` you can import XML configuration files). – M. Deinum Jan 19 '18 at 12:32
  • @M. Deinum hi, thanks! but what is the purpose of it then? I may use `@Import` - and this is it – Dmitry Senkovich Jan 19 '18 at 12:33
  • 2
    As stated to `@Import` (aka include, load etc) other java configuration classes. For instance those not covered by component scanning (or maybe you disabled component scanning for `@Configuration` files). Or to create a separate configuration for test which `@Import`s the original configuration so that you can override beans ... – M. Deinum Jan 19 '18 at 12:34
  • @M. Deinum ok, I got the first idea. but in the second I could simply put `@Import` on test class, why to use `@ContextConfiguration` here? sorry if I'm being stupid:) – Dmitry Senkovich Jan 19 '18 at 12:41
  • 2
    Because as I also already stated, `@Import` is only useful (and functional) on `@Configuration` classes. It won't do anything on a test class, the only thing it does is take up a line of code. – M. Deinum Jan 19 '18 at 12:42
  • @M. Deinum awesome, now I see. thank you very much! – Dmitry Senkovich Jan 19 '18 at 12:44
  • @Deinum - Wow thanks - I got the point it's just the other way around. But I have to disagree, using @Import(TestConfig.class) on my Test will import that Beans, if they are not defined in my AppConfig. Which is picked up by SpringBootTest. And that made me crazy - because if my AppConfig has that Bean defined, the Imported is ignored. Makes no sense. So don't do that. – Torsten Feb 13 '19 at 18:25

2 Answers2

23

@Import and @ContextConfiguration are for different use cases and cannot be used interchangeability.

The @Import is only useful for importing other @Configuration files and is only useful (and afaik) and functional on @Configuration classes. When putting the @Import on a test class it will be no good as it won't be processed.

@Configuration
@Import(PersistenceConfig.class)
public class MainConfig {}

Using @Import can be useful if for instance you have disabled component scanning for @Configuration classes or you need an @Configuration class from a package not covered by your component-scan.

Note: There is also @ImportResource which does the same for older XML based configuration files.

The reverse is valid for @ContextConfiguration as that is only useful on Spring based test classes (tests ran with the SpringRunner for jUnit 4). It is used to supply the test with the configuration parameters to make up the test configuration. It can be a collection of XML, javaconfig (or a combination thereof).

@RunWith(SpringRunner.class)
@ContextConfiguration( classes = {MainConfig.class, TestConfig.class})
public MyTest {}

It also allows to specify what to use to load those configuration (amongst others).

Konstantin
  • 3,626
  • 2
  • 33
  • 45
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • a note: `ContextCongifuration` can be used either with XML or Java configurations: > As of Spring 3.1, context loaders may choose to support either path-based or class-based resources. – Dmitry Senkovich Jan 19 '18 at 14:03
  • 17
    Well... you can actually annotate a test class with `@Import` when using Spring Boot. ;-) https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#boot-features-testing-spring-boot-applications-excluding-config – Sam Brannen Jan 21 '18 at 16:56
  • @SamBrannen but does it behave exactly the same? – davidcyp Nov 12 '19 at 14:04
  • 1
    This answer need correction. `@Import` can be used on Test class as well to import TestConfiguration. – Amith Kumar Apr 06 '23 at 20:02
15

in Spring Boot @Import(SomeConfiguration.class) adds configuration class to existing context. It is useful with test slices:

@DataJpaTest
@Import(SomeConfiguration.class)
class TestSomething(){...}

Here you have access to repositories and your beans from SomeConfiguration class.

@ContextConfiguration(classes = SomeConfiguration.class) mean use only this configuration , which could not work with eg. DataJpaTest.

LukaszSobczak
  • 171
  • 1
  • 5