@Bean vs @Autowired循环依赖

时间:2018-01-23 09:25:29

标签: spring dependency-injection jackson

我在@Bean课程中遇到了@Autowired@Configuration的奇怪行为。我的网络项目结构就像 控制器→服务→存储库

在我的服务中,我依赖于ObjectMapper

@Autowired
  public ServiceClass(final ObjectMapper objectMapper) {
    this.objectMapper = objectMapper;
  }

由于我想在反序列化时使用Java 8可选类,我想注册Jdk8Module。所以我创建了一个这样的配置类:

@Configuration
public class JacksonConfig {

@Bean
  public ObjectMapper objectMapper(final ObjectMapper objectMapper) {
    objectMapper.registerModule(new Jdk8Module());
    return objectMapper;
  }
}

我最初认为Spring会注入它拥有的objectMapper实例,我可以操作并返回它,这样当我在服务类中自动装配它时,我会获得更新的ObjectMapper实例。

但是我得到了一个循环依赖错误。这是可以理解的,因为我的bean配置依赖于objectmapper并返回一个objectmapper。

但令人惊讶的是,如果我将方法改为@Autowired而不是@Bean,那么Spring不会抱怨并按预期工作。

@Autowired
  public ObjectMapper objectMapper(final ObjectMapper objectMapper) {
    objectMapper.registerModule(new Jdk8Module());
    return objectMapper;
  }

为什么?

2 个答案:

答案 0 :(得分:0)

@Bean注释目标是从Spring BeanFactory提供bean。当方法注释@Bean时,它应该返回一个对象的新实例。如果Spring能够实例化它们,它可以使用参数。

在您的示例中,当您声明

@Bean
public ObjectMapper objectMapper(final ObjectMapper objectMapper) {
  objectMapper.registerModule(new Jdk8Module());
  return objectMapper;
}

这意味着你的ObjectMapper是一个bean(当然),它接受一个ObjectMapper实例的参数,而Spring知道ObjectMapper所以它可以使用...来实例化它。同样的方法。这是你的循环依赖。

对于@Autowired,Spring使用ObjectMapper作为BeanFactory中已有方法的参数。这就是它消除循环依赖的原因。

我希望我足够清楚。

这里很少提及:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html

答案 1 :(得分:0)

@Autowired
public ObjectMapper objectMapper(final ObjectMapper objectMapper) {
  objectMapper.registerModule(new Jdk8Module());
  return objectMapper;
}

其他人正在为此方法注入ObjectMapper(可能是Spring)。我认为在这种情况下不需要Autowired注释,Spring知道你想在这里注入一个bean。

在这种情况下,您不会创建新的bean,因此这里不会出现循环依赖性错误。

如果你想创建一个新的,也许你应该玩@Qualifier。

更多信息:https://dzone.com/articles/spring-configuration-and