Question

I spent some time resolving problem with missing org.joda.time.DateTime->java.util.Date converter in Spring Data (which should be enabled by default when Joda-Time is on a classpath). I have found a reason, but it generated a question about @Configuration annotation in Spring.

Standard application config using AbstractMongoConfiguration from spring-data-mongodb:

@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }

A test which explicit uses AppConfig class (with Spock, but internally mechanisms provided by spring-test are used):

@ContextConfiguration(classes = AppConfig)
class JodaDocRepositorySpec extends Specification {

    @Autowired
    private JodaDocRepository jodaDocRepository

    def "save document with DateTime"() {
        given:
            def jodaDoc = new JodaDoc(DateTime.now())
        when:
            def savedJodaDoc = jodaDocRepository.save(jodaDoc)
        then:
            savedJodaDoc.id
    }
}

It works fine. But when @Configuration annotation in AppConfig is removed/commented:

//@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }

the test fails with:

org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting from type org.joda.time.DateTime to type java.util.Date

AFAIK it is not needed to use @Configuration for the configuration class when it is explicit registered in the context (by classes in @ContextConfiguration or a register() method in AnnotationConfigWebApplicationContext). The classes are processed anyway and all declared beans are found. It is sometimes useful to not use @Configuration to prevent detecting by a component scan when there are 2 similar configuration classes in the same packages in a test context used by different tests.

Therefor I think it could a bug in Spring which causes to different internal beans processing in the context depending on an usage or not a @Configuration annotation. I compared Spring logs from these two cases and there are some differences, but I'm not able to determine what are they caused by in the Spring internal classes. Before a bug submission I would like to ask:

My question. Is there an explicable reason why Spring for the same configuration class (pointed explicit in @ContextConfiguration) uses (or not) converters for Joda-Time depending on an existence of a @Configuration annotation?

I created also a quickstart project reproducing the issue. spring-data-mongodb 1.3.3, spring 4.0.0, joda-time 2.3.

Was it helpful?

Solution

It's everything OK in this behaviour. AbstractMongoConfiguration is annotated by @Configuration, but in fact this annotation is not @Inherited, so you have to explicitly annotate your class.

When you remove @Configuration annotation then your AppConfig class is not a full configuration. It's processes as a lite configuration just because it contains methods annotated by @Bean - please refer to methods in org.springframework.context.annotation.ConfigurationClassUtils

  • isFullConfigurationCandidate()
  • isLiteConfigurationCandidate()
  • isFullConfigurationClass()

Finally only full (annotated by @Configuration) configuration classes are processes and enhanced by configuration post processors - look at ConfigurationClassPostProcessor.enhanceConfigurationClasses()

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