Reputation: 4126
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.
Upvotes: 4
Views: 984
Reputation: 14149
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()
Upvotes: 3