我应该将配置类注释为@Configuration进行测试吗? [英] Should I annotate configuration class as @Configuration for testing?

查看:139
本文介绍了我应该将配置类注释为@Configuration进行测试吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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

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

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

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

工作正常.但是,当删除/注释了AppConfig中的@Configuration批注时:

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

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

AFAIK,当在上下文中显式注册配置类时,不需要对配置类使用@Configuration(通过@ContextConfiguration中的类或AnnotationConfigWebApplicationContext中的register()方法).无论如何,都将处理这些类,并且会找到所有已声明的bean.在不同测试使用的测试上下文中,同一程序包中有2个相似的配置类时,有时不使用@Configuration来防止通过组件扫描进行检测是很有用的.

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.

因此,我认为这可能是Spring中的错误,根据使用情况或@Configuration批注,这会导致上下文中不同的内部bean处理.我比较了这两种情况下的Spring日志,但有一些区别,但是我无法确定它们在Spring内部类中是由什么引起的.在提交错误之前,我想问一下:

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:

我的问题.是否存在一个明确的原因,即为什么针对同一配置类(在@ContextConfiguration中明确指出)的Spring使用(或不使用)Joda-Time转换器,具体取决于是否存在@Configuration批注?

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?

我还创建了一个 quickstart项目重现了该问题. spring-data-mongodb 1.3.3,spring 4.0.0,joda-time 2.3.

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

推荐答案

在此行为中,一切正常. AbstractMongoConfiguration@Configuration注释,但实际上该注释不是@Inherited,因此您必须显式注释您的类.

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.

删除@Configuration批注时,您的AppConfig类不是完整配置.由于它包含@Bean注释的方法,因此它是 lite 配置的过程-请参考org.springframework.context.annotation.ConfigurationClassUtils

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()
  • isFullConfigurationCandidate()
  • isLiteConfigurationCandidate()
  • isFullConfigurationClass()

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

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

这篇关于我应该将配置类注释为@Configuration进行测试吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆