Spring 引导 2.x Jackson ObjectMapper 实例未注入服务 class - 尝试了默认引导和配置中的 bean 方法 class
Spring Boot 2.x Jackson ObjectMapper instance does not get injected in service class - tried both boot default & with bean method from config class
我看到用 Spring Boot 2.3.4.RELEASE.
注入 Jackson ObjectMapper
时出现奇怪的行为
我的 Maven 依赖项中有 spring-boot-starter-web
和 spring-boot-starter-json
。然而,当我在我的 @Service
classes 之一中自动连接 ObjectMapper
时,它没有被注入并且引用为空。
然后我尝试在 @Configuration
class 的 @Primary
@Bean
bean 方法中手动创建并返回一个,但结果仍然相同。
我知道 @Configuration
工作正常,因为其中的其他 bean 方法用于正确注入其他对象。此外,我还在 bean 方法中添加了一个日志语句,即 returns ObjectMapper
实例也被记录,但 @Service
class 上的引用仍然为空? (我也试过添加@AutoConfigureAfter(JacksonAutoConfiguration.class)
,但没有成功)
还有其他人遇到过这个问题或知道这里发生了什么吗?请投光..
谢谢
编辑 (10/22):下面是 @Service
class、
的片段
@Lazy
@Service
@EnableSpringConfigured
public class SampleServiceSingletonService {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleServiceSingletonService.class);
@Autowired
protected ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Autowired
private ObjectMapper objectMapper;
@EventListener({ApplicationReadyEvent.class})
private void initOnAppReady() {
LOGGER.info("No need to create ObjectMapper instances, most customizations can be set/overriden in application.properties, look at the one here for reference");
LOGGER.info("Injected ObjectMapper: {}", objectMapper);
LOGGER.info("Init on app ready complete..");
//...
}
编辑 2 (10/22):对于遇到此问题的其他人,
问题似乎是(感谢下面的@M.Deinum)实例化 and/or 注入似乎并没有在 ApplicationReadyEvent
被触发时发生,它的事件处理程序是调用。这对我来说似乎很奇怪,原因有二,一是根据文档,事件是 "published as late as conceivably possible to indicate that the application is ready to service requests...since all initialization steps will have been completed by then",二是直到现在我还没有在其他对象的其他注入中看到这种行为,所以我从不怀疑这是一个原因。下面是我看到注入工作的片段,
@Lazy
@Service
public class SampleServiceSingletonService {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleServiceSingletonService.class);
@Autowired
public ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Autowired
public ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired
public ObjectMapper objectMapper;
@EventListener(ApplicationReadyEvent.class)
private void initOnAppReady() {
// Its null here..
//LOGGER.info("The Injected ObjectMapper: {}", objectMapper);
LOGGER.info("Init on app ready complete..");
runAsync();
}
@Async
public void runAsync() {
LOGGER.info("This is run asynchronously.");
// Its no longer null here
LOGGER.info("The Injected ObjectMapper: {}", objectMapper);
}
}
谢谢
您应该将 setter
和 getter
添加到您的
private ObjectMapper objectMapper;
所以Spring可以给它赋值
您已用 @Lazy
标记了您的豆子。当放在一个类型上时,会为该对象创建一个惰性代理。在这种情况下,将创建一个基于 class 的代理(class 上没有接口),为此将创建一个 subclass 来添加惰性行为。
然而,由于您的方法是 private
,因此无法在动态创建的 class 中覆盖此方法,因此它将在代理上调用或通过代理进行中继到实际对象。代理对象不会注入任何依赖项,至少 private
字段不会。
所以要修复,请使您的方法 protected
或 public
以便它可以被正确地子 classes 和覆盖。如果不需要,也可以删除 @Lazy
。
有关更详细的说明,请参阅 this blog。
我看到用 Spring Boot 2.3.4.RELEASE.
注入 JacksonObjectMapper
时出现奇怪的行为
我的 Maven 依赖项中有 spring-boot-starter-web
和 spring-boot-starter-json
。然而,当我在我的 @Service
classes 之一中自动连接 ObjectMapper
时,它没有被注入并且引用为空。
然后我尝试在 @Configuration
class 的 @Primary
@Bean
bean 方法中手动创建并返回一个,但结果仍然相同。
我知道 @Configuration
工作正常,因为其中的其他 bean 方法用于正确注入其他对象。此外,我还在 bean 方法中添加了一个日志语句,即 returns ObjectMapper
实例也被记录,但 @Service
class 上的引用仍然为空? (我也试过添加@AutoConfigureAfter(JacksonAutoConfiguration.class)
,但没有成功)
还有其他人遇到过这个问题或知道这里发生了什么吗?请投光..
谢谢
编辑 (10/22):下面是 @Service
class、
@Lazy
@Service
@EnableSpringConfigured
public class SampleServiceSingletonService {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleServiceSingletonService.class);
@Autowired
protected ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Autowired
private ObjectMapper objectMapper;
@EventListener({ApplicationReadyEvent.class})
private void initOnAppReady() {
LOGGER.info("No need to create ObjectMapper instances, most customizations can be set/overriden in application.properties, look at the one here for reference");
LOGGER.info("Injected ObjectMapper: {}", objectMapper);
LOGGER.info("Init on app ready complete..");
//...
}
编辑 2 (10/22):对于遇到此问题的其他人,
问题似乎是(感谢下面的@M.Deinum)实例化 and/or 注入似乎并没有在 ApplicationReadyEvent
被触发时发生,它的事件处理程序是调用。这对我来说似乎很奇怪,原因有二,一是根据文档,事件是 "published as late as conceivably possible to indicate that the application is ready to service requests...since all initialization steps will have been completed by then",二是直到现在我还没有在其他对象的其他注入中看到这种行为,所以我从不怀疑这是一个原因。下面是我看到注入工作的片段,
@Lazy
@Service
public class SampleServiceSingletonService {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleServiceSingletonService.class);
@Autowired
public ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Autowired
public ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired
public ObjectMapper objectMapper;
@EventListener(ApplicationReadyEvent.class)
private void initOnAppReady() {
// Its null here..
//LOGGER.info("The Injected ObjectMapper: {}", objectMapper);
LOGGER.info("Init on app ready complete..");
runAsync();
}
@Async
public void runAsync() {
LOGGER.info("This is run asynchronously.");
// Its no longer null here
LOGGER.info("The Injected ObjectMapper: {}", objectMapper);
}
}
谢谢
您应该将 setter
和 getter
添加到您的
private ObjectMapper objectMapper;
所以Spring可以给它赋值
您已用 @Lazy
标记了您的豆子。当放在一个类型上时,会为该对象创建一个惰性代理。在这种情况下,将创建一个基于 class 的代理(class 上没有接口),为此将创建一个 subclass 来添加惰性行为。
然而,由于您的方法是 private
,因此无法在动态创建的 class 中覆盖此方法,因此它将在代理上调用或通过代理进行中继到实际对象。代理对象不会注入任何依赖项,至少 private
字段不会。
所以要修复,请使您的方法 protected
或 public
以便它可以被正确地子 classes 和覆盖。如果不需要,也可以删除 @Lazy
。
有关更详细的说明,请参阅 this blog。