如何声明另一个杰克逊ObjectMapper不影响原豆的“客户”?

依婷:

我有一个公开JSON REST API弹簧启动应用程序。用于将对象映射到JSON它使用内置的杰克逊ObjectMapper配置成通过弹簧引导。

现在,我需要从一个YAML文件中读取一些数据,我发现一个简单的方法来做到这一点是利用杰克逊 - 为了这个,我需要声明一个不同的ObjectMapper转换YAML对象。我宣布这个新的映射豆具有特定名称,以便能够从YAML文件中读取注入它在我的服务交易:

@Bean(YAML_OBJECT_MAPPER_BEAN_ID)
public ObjectMapper yamlObjectMapper() {
    return new ObjectMapper(new YAMLFactory());
}

但我需要一种方法来告诉原来的JSON ObjectMapper的其他所有“客户”使用bean来保持。所以基本上我需要在原豆一@Primary注解。有没有办法实现这一目标,而不必重新声明原ObjectMapper在我自己的配置(我不得不通过弹簧引导代码挖找到并复制它的配置)?

一个解决方案,我发现是声明一个FactoryBean为ObjectMapper并使其返回已声明豆,在提出这个答案我发现通过调试我原来的豆腐被称为“_halObjectMapper”,所以我的FactoryBean将搜索这个bean,并返回它:

public class ObjectMapperFactory implements FactoryBean<ObjectMapper> {

    ListableBeanFactory beanFactory;

    public ObjectMapper getObject() {
        return beanFactory.getBean("_halObjectMapper", ObjectMapper.class);
    }
    ...
}

然后在我的配置I类声明为@Primary豆,以确保它是自动装配的首选:

@Primary
@Bean
public ObjectMapperFactory objectMapperFactory(ListableBeanFactory beanFactory) {
    return new ObjectMapperFactory(beanFactory);
}

不过,我不是100%满意这个解决方案,因为它依赖于它是不是我的控制下的bean的名字,也似乎是一个黑客。是否有一个清晰的解决方案?

谢谢!

达山梅塔:

您可以定义两个ObjectMapper豆类和一个声明为一级,如:

@Bean("Your_id")
public ObjectMapper yamlObjectMapper() {
    return new ObjectMapper(new YAMLFactory());
}

@Bean
@Primary
public ObjectMapper objectMapper() {
    return new ObjectMapper();
}

一旦这样做,你可以用你的objectmapper豆@Qualifier注释,例如:

@Autowired
@Qualifier("Your_id")
private ObjectMapper yamlMapper;

更新

您可以动态地添加ObjectMapper到Spring的bean工厂在运行时,如:

@Configuration
public class ObjectMapperConfig {

    @Autowired
    private ConfigurableApplicationContext  context;

    @PostConstruct
    private void init(){
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ObjectMapper.class);
        builder.addConstructorArgValue(new JsonFactory());
        DefaultListableBeanFactory factory = (DefaultListableBeanFactory) context.getBeanFactory();
        factory.registerBeanDefinition("yamlMapper", builder.getBeanDefinition());
        Map<String, ObjectMapper> beans = context.getBeansOfType(ObjectMapper.class);
        beans.entrySet().forEach(System.out::println);
    }
}

上面的代码添加一个新的豆到context在不改变现有的bean(sysout打印中的端部两个bean init方法)。然后,您可以使用“yamlMapper”作为限定词的任何地方自动装配它。

更新2(从提问作者):

在“更新”工作建议,并在此解决方案的简化版本:

@Autowired
private DefaultListableBeanFactory beanFactory;

@PostConstruct
private void init(){
    BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(YAMLMapper.class);
    beanFactory.registerBeanDefinition("yamlMapper", builder.getBeanDefinition());
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何将几个参数移动到杰克逊的另一个节点?

杰克逊ObjectMapper writeValueAsBytes方法向已经包含反斜杠的字符串中添加另一个反斜杠

杰克逊反电子化:根源上的两个关键。我如何解开一个而忽略另一个?

从杰克逊的一个对象到另一个对象的属性的深层复制?

基于另一个字段映射JSON字段(为一个值),使用杰克逊(这是一个键)

如何序列化一个列表的内容与杰克逊平坦JSON对象?

如何获得一个类,杰克逊的看法它的属性列表?

杰克逊(Jackson):当类名更改并且类从另一个类继承时,序列化应该更改吗?

我想使用杰克逊库将嵌套在另一个对象中的json对象映射到POJO

杰克逊(Jackson):杰森(Json)具有到Java类的json数组,该数组具有另一个Java类的列表

如何使用杰克逊ObjectMapper解析Mongodb的UUID对象?

如何分析领域可能是一个字符串,并且可以与杰克逊的数组

杰克逊ObjectMapper默认属性顺序

杰克逊ObjectMapper:readValue返回null

创建杰克逊ObjectMapper实例的副本

奇怪的杰克逊ObjectMapper行为

杰克逊的RESTEasy和ContextResolver <ObjectMapper>

从另一个分支获取更改,而根本不影响当前分支

捕获和处理异常杰克逊用一个自定义消息

杰克逊解串器委托给一个适用的解串器

解析JSON使用杰克逊:我们可以在一个POJO可选变量

映射一个JSON字符串与杰克逊对象将抛出MismatchedInputException

杰克逊-反序列化一个基本枚举

杰克逊在春季启动错误序列化一个ZonedDateTime

传递一个手动的内容创建的JSONObject杰克逊

杰克逊:如果有多个串行器,则使用哪一个?

杰克逊默认解析为一个子类

杰克逊无法使用一个参数构造器构造实例

杰克逊的平面 JSON 用于一个字段的类/记录