4

我花了一些时间解决org.joda.time.DateTime->java.util.DateSpring Data 中缺少转换器的问题(当 Joda-Time 在类路径上时,它应该默认启用)。我找到了一个原因,但是它在 Spring 中产生了一个关于@Configuration注解的问题。

AbstractMongoConfiguration使用来自 spring-data-mongodb 的标准应用程序配置:

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

显式使用 AppConfig 类的测试(使用 Spock,但使用 spring-test 提供的内部机制):

@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
    }
}

它工作正常。但是当 AppConfig 中的 @Configuration 注释被删除/注释时:

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

测试失败:

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

@ConfigurationAFAIK当它在上下文中显式注册时(通过类中的类@ContextConfigurationregister()方法) ,不需要将其用于配置类AnnotationConfigWebApplicationContext。无论如何都会处理这些类,并找到所有声明的 bean。@Configuration当不同测试使用的测试上下文中的相同包中有 2 个相似的配置类时,不使用它来防止组件扫描检测有时很有用。

因此,我认为它可能是 Spring 中的一个错误,它会导致上下文中不同的内部 bean 处理取决于使用或不是@Configuration注释。我比较了这两种情况的 Spring 日志,存在一些差异,但我无法确定它们是由 Spring 内部类引起的。在提交错误之前,我想问一下:

我的问题。是否有一个可以解释的原因为什么相同配置类的 Spring(显式指出@ContextConfiguration)使用(或不使用)Joda-Time 转换器取决于@Configuration注释的存在?

我还创建了一个快速启动项目来重现该问题。spring-data-mongodb 1.3.3,spring 4.0.0,joda-time 2.3。

4

1 回答 1

3

这种行为一切正常。AbstractMongoConfiguration由 注释@Configuration,但实际上此注释不是@Inherited,因此您必须显式注释您的类。

当您删除@Configuration注释时,您的AppConfig类不是完整的配置。它是一个精简配置的过程,只是因为它包含注释的方法@Bean- 请参阅方法org.springframework.context.annotation.ConfigurationClassUtils

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

最后,只有完整的(由 注释的@Configuration)配置类是进程并由配置后处理器增强 - 看看ConfigurationClassPostProcessor.enhanceConfigurationClasses()

于 2014-01-15T21:12:31.413 回答