smeeb smeeb - 8 months ago 81
Groovy Question

How is Spring Boot configuring my Jackson ObjectMapper here?

I'm trying to understand how Spring/Spring Boot is managing DI for an app that I've been put in charge of maintaining. Inside that app I see a

MyAppInjector
Groovy file that looks like this:

@Configuration
class MyAppInjector {
@Autowired
void configureJackson(ObjectMapper objectMapper) {
SimpleModule jacksonModule = new SimpleModule()
.addDeserializer(AccountDeserializer, new AccountDeserializer())
.addDeserializer(PhoneNumberDeserializer, new PhoneNumberDeserializer())
.addDeserializer(AddressDeserializer, new AddressDeserializer())
.addDeserializer(ContactDeserializer, new ContactDeserializer())
.addDeserializer(CustomerDeserializer, new CustomerDeserializer())
.addDeserializer(DeploymentInfoDeserializer, new DeploymentInfoDeserializer())
.addDeserializer(ServiceAgreementDeserializer, new ServiceAgreementDeserializer())

objectMapper.registerModule(jacksonModule)
}
}


However I don't see
configureJackson(...)
invoked from anywhere inside my app source code. I assume that this method is configuring the Jackson
ObjectMapper
, used by Spring to serialize JSON into POJOs.

However, how does Spring know to configure the
ObjectMapper
here? Does it look for anything annotated with
@Configuration
and then see it has a Jackson
ObjectMapper
registered somewhere, and pass it into this
configureJackson(...)
method? Looks like magic to me...

And is this true of any method in a class annotated with
@Configuration
? Meaning can I create a method like:

@Configuration
class MyAppInjector {
@Autowired
Fizz fizz(Buzz buzz) {
new Fizz(buzz)
}

@Autowired
void configureJackson(ObjectMapper objectMapper) {
SimpleModule jacksonModule = new SimpleModule()
.addDeserializer(AccountDeserializer, new AccountDeserializer())
.addDeserializer(PhoneNumberDeserializer, new PhoneNumberDeserializer())
.addDeserializer(AddressDeserializer, new AddressDeserializer())
.addDeserializer(ContactDeserializer, new ContactDeserializer())
.addDeserializer(CustomerDeserializer, new CustomerDeserializer())
.addDeserializer(DeploymentInfoDeserializer, new DeploymentInfoDeserializer())
.addDeserializer(ServiceAgreementDeserializer, new ServiceAgreementDeserializer())

objectMapper.registerModule(jacksonModule)
}
}


...and expect Spring to intelligently look for a
Buzz
instance to pass into the
Fizz
at construction-time?

Answer Source

SpringBoot instantiates ObjectMapper on its own, as it is used by Spring in convert Java object to JSON and vice versa. So if it finds Spring boot in the classpath it will load the objectMapper. Now in your configureJackson method, you have reference of ObjectMapper and @Autowired annotation so Spring will provide the instance of ObjectMapper to this method.

The @Autowired annotation is doing the magic which you are referring to. @Autowired

Fizz fizz(Buzz buzz) {
  new Fizz(buzz)
} 

In this example Apring will inject the Buzz instance in fizz method.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download