This is the ninth day of my participation in the First Challenge 2022

The problem

  • This invalidates SpringBoot’s native ObjectMapper configuration when a custom ObjectMapper is registered as a Bean

why

  • Because the custom ObjectMapper overrides the native ObjectMapper configuration in SpringBoot, only the custom ObjectMapper takes effect

To solve

Methods a

  • According to the originalObjectMapperIn the source code@ConditionalOnMissingBean(ObjectMapper.class)Can know:
    • The native ObjectMapper configuration takes effect only when no other ObjectMapper is present in the project
  • So you can customize itObjectMapperadd@ConditionalOnBeanComments:
    • Causes custom ObjectMapper to be registered only after the native ObjectMapper appears
    • Because the native ObjectMapper has @primary, the native ObjectMapper is preferred

Method 2

  • Through the use of@ConditionOnBeanAnnotations enableObjectMapperIt doesn’t go away, but it does lead to oneCrudMapperVanishing problem:
    • You can use @dependson to control the initialization order of beans. Cause the custom ObjectMapper to be initialized after the native jsonHandler has been loaded, since the default ObjectMapper has already been loaded

Methods three

  • Through the use of@DependsOnTo solve theObjectMapperandCrudeMapperThe vanishing problem, however, raises the problem of cyclic dependency:
    • Since the new ObjectMapper is a subclass of ObjectMapper, the default ObjectMapper does not register once it finds beans with the remaining ObjectMapper
    • This results in the remaining default ObjectMapper beans making references to the new ObjectMapper. This leads to the problem of circular dependencies
  • Solutions:
    • Erasing the original type signature by using a generic type as the return type
    • This eliminates the ObjectMapper Bean definition in config, allowing Jackson’s default ObjectMapper to be loaded
    • Then add the @dependson annotation after the jsonHandler to ensure that the default ObjectMapper occurs
  • Note:
    • In Java’s Annotation configuration, the default ID of a Bean is the name of the method that uses the @bean Annotation
    • The default assembly of the @autowired annotation is ByType
    • @ResourceThe annotation default assembly isByName
      • By erasing the type, you can prevent loop dependencies caused by ByType assembly
      • But ByType assembly cannot be used after the class type is erased
    • After erasing the type, you need to inject a new ObjectMapper using @Resource

conclusion

  • SpringBoot and Bean notes:
annotations parameter instructions
@ConditionalOnBean The class object of the type-bean

The name of the value-bean
The content modified by this annotation is only effective if the specified Bean exists
@ConditionalOnMissingBean The class object of the type-bean

The name of the value-bean
The content modified by this annotation is only effective if the specified Bean does not exist
@ConditionOnClass Name – the name of the class

Value – The class object of the class
What this annotation modifies is only effective if the class exists
@ConditionalOnMissingClass Value – the name of the class This annotation is only useful if the class does not exist
@Conditional An implementation class for the value-condition interface Determines whether to validate the embellished content based on the specified category
@DependsOn Value (String[] Bean name) Annotate the Bean on which the current Bean needs to depend. The Bean modified by this annotation does not take effect until the specified Bean has been initialized
annotations instructions
@Primary Beans decorated with this annotation are preferred