- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的 Spring Boot 项目中,我使用默认的 Jackson ObjectMapper。我想将新的 ObjectMapper 添加到 Spring Context 并开始在新的地方使用它,但也保留默认的。添加新的 @Bean 定义将覆盖默认的 ObjectMapper。如何添加新的 ObjectMapper Bean 而不覆盖前一个?
最佳答案
是的,@ConditionalOnMissingBean
是[很难]被破解的。通过一个简单的技巧(亚洲哲学),我们可以绕过这个问题/让它不再有问题:
将您的(1+,自动配置,@ConditionalOnMissing...
)bean 包装在其他/自定义/“包装器”中。 (代价是:引用1+/思考差异/更复杂)
提到MappingJackson2HttpMessageConverter
( auto-config here ) 具有这种(内置)功能(和目的),可以根据“http 转换”映射到多个对象映射器。
因此,使用(通用的,例如基于 java.util.Map 的)类似的东西:
class MyWrapper<K, V> {
final Map<K, V> map;
public MyWrapper(Map<K, V> map) {
this.map = map;
}
public Map<K, V> getMap() {
return map;
}
}
我们可以接线:
@Bean
MyWrapper<String, ObjectMapper> myStr2OMWrapper(/*ObjectMapper jacksonOm*/) {
return new MyWrapper(Map.of(
// DEFAULT, jacksonOm,
"foo", fooMapper(),
"bar", barMapper()
));
}
..其中 fooMapper()
和 barMapper()
可以引用(静态/实例)no-bean 方法:
private static ObjectMapper fooMapper() {
return new ObjectMapper()
.configure(SerializationFeature.INDENT_OUTPUT, true) // just a demo...
.configure(SerializationFeature.WRAP_ROOT_VALUE, true); // configure/set as see fit...
}
private static ObjectMapper barMapper() {
return new ObjectMapper()
.configure(SerializationFeature.INDENT_OUTPUT, false) // just a demo...
.configure(SerializationFeature.WRAP_ROOT_VALUE, false); // configure/set more...
}
(已经)测试/使用时间:
package com.example.demo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoAppTests {
@Autowired
MyWrapper<String, ObjectMapper> my;
@Autowired
ObjectMapper jacksonOM;
@Test
void contextLoads() {
System.err.println(jacksonOM);
Assertions.assertNotNull(jacksonOM);
my.getMap().entrySet().forEach(e -> {
System.err.println(e);
Assertions.assertNotNull(e.getValue());
});
}
}
打印(例如)
...
com.fasterxml.jackson.databind.ObjectMapper@481b2f10
bar=com.fasterxml.jackson.databind.ObjectMapper@577bf0aa
foo=com.fasterxml.jackson.databind.ObjectMapper@7455dacb
...
Results:
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
...
抱歉,此测试不验证(单独)配置,而只是:(视觉上不同)不是空对象映射器。
如何启用(多个!)my.custom.jackson.*
自动配置,是一个更复杂的问题...(它不像 my.custom.datasource.*
config ;(
与:
@Bean
@Primary // ! for auto config, we need one primary (whether it is "spring.jackson" ... adjust;)
@ConfigurationProperties("spring.jackson")
JacksonProperties springJacksonProps() {
return new JacksonProperties();
}
@Bean
@ConfigurationProperties("foo.jackson")
JacksonProperties fooProps() {
return new JacksonProperties();
}
@Bean
@ConfigurationProperties("bar.jackson")
JacksonProperties barProps() {
return new JacksonProperties();
}
我们已经可以加载和区分(完整的)配置,例如:
spring.jackson.locale=en_US
spring.jackson.time-zone=UTC
# ... all of spring.jackson @see org.springframework.boot.autoconfigure.jackson.JacksonProperties
foo.jackson.locale=en_US
foo.jackson.time-zone=PST
# ... just for demo purpose
bar.jackson.locale=de_DE
bar.jackson.time-zone=GMT+1
并且(没问题)将它们(props)传递给相应的(static [foo|bar]Mapper
)方法......但是然后呢? (如果你擅长的话,你可以停止阅读这里!:)
不幸的是according ("state of art") code (将 JacksonProperties
与“om builder”连接)不是公开的(即不可扩展/可插入)。
相反,自动配置提供(如果没有定义/@ConditionalOnMissingBean
):
Jackson2ObjectMapperBuilder
bean,它(每次请求时):
Jackson2ObjectMapperBuilderCustomizer
beans 的定制。JacksonProperties
到 Jackson2ObjectMapperBuilder
...所以最简单的方法似乎(最新)是:
Jackson2ObjectMapperBuilderCustomizer
)例如(在生产之前回顾+测试!)非接口(interface),返回一个Jackson2ObjectMapperBuilder
,模仿自动配置,不应用(其他)定制器/-ation:
// ...
import com.fasterxml.jackson.databind.Module; // !! not java.lang.Module ;)
// ...
private static class MyStolenCustomizer {
private final JacksonProperties jacksonProperties;
private final Collection<Module> modules;
// additionally need/want this:
private final ApplicationContext applicationContext;
// copy/adopt from spring-boot:
private static final Map<?, Boolean> FEATURE_DEFAULTS = Map.of(
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false,
SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false
);
public MyStolenCustomizer(
ApplicationContext applicationContext,
JacksonProperties jacksonProperties,
Collection<Module> modules
) {
this.applicationContext = applicationContext;
this.jacksonProperties = jacksonProperties;
this.modules = modules;
}
// changed method signature!!
public Jackson2ObjectMapperBuilder buildCustom() {
// mimic original (spring-boot) bean:
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.applicationContext(applicationContext);
// without (additional!) customizers:
if (this.jacksonProperties.getDefaultPropertyInclusion() != null) {
builder.serializationInclusion(this.jacksonProperties.getDefaultPropertyInclusion());
}
if (this.jacksonProperties.getTimeZone() != null) {
builder.timeZone(this.jacksonProperties.getTimeZone());
}
configureFeatures(builder, FEATURE_DEFAULTS);
configureVisibility(builder, this.jacksonProperties.getVisibility());
configureFeatures(builder, this.jacksonProperties.getDeserialization());
configureFeatures(builder, this.jacksonProperties.getSerialization());
configureFeatures(builder, this.jacksonProperties.getMapper());
configureFeatures(builder, this.jacksonProperties.getParser());
configureFeatures(builder, this.jacksonProperties.getGenerator());
configureDateFormat(builder);
configurePropertyNamingStrategy(builder);
configureModules(builder);
configureLocale(builder);
configureDefaultLeniency(builder);
configureConstructorDetector(builder);
// custom api:
return builder; // ..alternatively: builder.build();
}
// ... rest as in https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java#L223-L341
要连接模块
,我们可以(希望像最初一样)依赖:
@Autowired
ObjectProvider<com.fasterxml.jackson.databind.Module> modules
像这样初始化它们:
@Bean
MyStolenCustomizer fooCustomizer(ApplicationContext context, @Qualifier("fooProps") JacksonProperties fooProperties, ObjectProvider<Module> modules) {
return new MyStolenCustomizer(context, fooProperties, modules.stream().toList());
}
@Bean
MyStolenCustomizer barCustomizer(ApplicationContext context, @Qualifier("barProps") JacksonProperties barProperties, ObjectProvider<Module> modules) {
return new MyStolenCustomizer(context, barProperties, modules.stream().toList());
}
..并像这样使用它们:
@Bean
MyWrapper<String, Jackson2ObjectMapperBuilder> myStr2OMBuilderWrapper(
@Qualifier("fooCustomizer") MyStolenCustomizer fooCustomizer,
@Qualifier("barCustomizer") MyStolenCustomizer barCustomizer) {
return new MyWrapper(
Map.of(
"foo", fooCustomizer.buildCustom(),
"bar", barCustomizer.buildCustom()
)
);
}
...避免“双重定制”/保持 JacksonAutoConfiguration
启用/完整/Activity 。
问题:时间/更新(/外部代码)!
关于java - 如何在 Spring Boot 项目中添加新的 ObjectMapper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74874123/
有人可以解释一下 spring-boot-parent 和 spring-boot-starter-parent 之间的区别吗,正如我在下面附加的 GIT HUB 代码链接之一中看到的,他们为 spr
我有与 jersey 框架集成的 Spring Boot 应用程序。 现在,当我尝试运行该应用程序时,它只是停留在 Spring 启动徽标上,之后没有任何 react 。 我也尝试添加 -X ,但徽标
我指的是 Spring Boot 关于 的文档自动配置 和 执行器 模块: 自动配置: Spring Boot AutoConfiguration attempts to automatically
我正在尝试将 apache log4j 集成到我的 Spring boot 应用程序中。这是我的 build.gradle 文件: build.gradle buildscript { rep
使用 Spring Boot Maven 插件的以下命令在生产中启动 Spring Boot 应用程序是否是一个好主意或实践? mvn spring-boot:run 最佳答案 不,这是个坏主意。 您
据我所知,spring boot 和 spring session 为我们提供了一站式自动配置,但是当我的应用程序使用 session redis 和应用程序缓存 redis 时,不是同一个 redi
我希望使用Spring Boot创建一个新的Web应用程序。不幸的是,我的服务器在技术堆栈方面相当有限。它安装了Java 5。 谁能告诉我spring boot是否可以在Java 1.5上运行以及什么
我有3个实体 CarWash(设置Wash) Wash(car_wash_id FK到CarWash) WashComment(wash_id FK到Wash) 有什么办法可以写这个查询 @Qu
我一直在关注this文章。 我正在尝试在Spring-boot应用程序中优雅地处理gRPC错误,的主要目标是能够在gRPC客户端中获取错误状态。 在上面的文章之后,我坚持为异常添加拦截器。如何在Spr
我有一个要使用的自定义log4j布局插件。在IntelliJ中运行或与./gradlew bootRun一起运行时,插件可以正常工作。不使用./gradlew bootJar构建启动jar。 启用-D
我想在给定范围 (5001-5100) 的随机端口上启动 Spring Cloud 应用程序(Spring Boot 1.5.14,Spring Cloud Edgware.SR4)。我知道我们可以使
任何人都可以向我展示或指出不使用 spring boot gradle 插件的 spring boot gradle 项目。 我正在寻找类似不使用 gradle 插件的 spring boot sta
我当时尝试包含上述依赖项之一,但找不到任何区别: spring boot starter web:我可以看到 Flux 和 Mono 类并制作一个响应式(Reactive)休息 Controller
我们一直在为我们的应用程序使用 Springboot 1.X。 现在准备开始一些新的应用程序,想知道我们是应该使用 SpringBoot2.0 还是坚持使用 SpringBoot 1.X? 对一种方式
我希望记录应用程序正在加载 application-profile.propeties 或 application.yml。怎么做。在哪种方法中,我可以听取它并检测它是成功加载还是失败。 最佳答案 您
当我在 pom.xml 中添加简单的 spring-boot-starter-data-jpa 依赖项时,在 pom.xml 文件中出现错误。如果我删除该依赖项,则不会再有错误。我不确定为什么会发生这
我希望记录应用程序正在加载 application-profile.propeties 或 application.yml。怎么做。在哪种方法中,我可以听取它并检测它是成功加载还是失败。 最佳答案 您
我在网上看了很多关于 spring-boot-devtools 的文章和问题,但仍然无法弄清楚为什么它对我不起作用。每次运行我的应用程序时,我都会得到以下信息: 17:54:28.057 [main]
我正在尝试将现有的 Spring 应用程序移植到 Spring Boot。我不使用 spring-boot-starter-data-solr 启动器,但是我的类路径上有 apache solrj (
(这主要是一个历史问题。Pivotal 建议所有论坛讨论都在 StackOverflow 上进行,这就是我在这里问它的原因。) Spring Boot 项目用来证明将应用程序的类和依赖项从可执行 ja
我是一名优秀的程序员,十分优秀!