【问题标题】:@Bean annotation not working in Spring Boot@Bean 注解在 Spring Boot 中不起作用
【发布时间】:2020-03-19 07:23:50
【问题描述】:

我创建了模型

@Repository
public class Model {
    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Model(String name) {
        super();
        this.name = name;
    }

    public Model() {
        super();
        // TODO Auto-generated constructor stub
    }
}

然后我用一个bean创建了配置类

@Component
public class Config {

    @Bean
    public Model beanB() {
        Model a=new Model();
        a.setName("Daniel3");
        return a;
    }   
}

然后我创建了 Controller 类

@RestController
public class TestController {

    @Autowired
    Model model;

    @GetMapping("/test")
    @ResponseBody
    public Model test() {
        return model;
    }

}

当我点击控制器 url 时,我得到以下响应

{"name":null}

但是如果我修改配置类为

    @Bean
    @Primary
    public Model beanB() {
        Model a=new Model();
        a.setName("test");
        return a;
    }   

我得到的输出为 {"name":"test"} 。 我在使用 Autowired Model 而不是 new Model() 时观察到相同的行为

谁能解释这种行为?

【问题讨论】:

  • Model 类的全称是什么?
  • 使用@Repository 注释错误。请阅读spring.io/projects/spring-framework#learn 的文档以了解有关注释含义和使用位置的更多信息。这是一个模型类,应该在每个请求中实例化,因为状态会改变。
  • 如果您只是在测试 Bean 创建的工作原理,@rieckpil 在下面回答了您的问题 :)
  • 使用@RestController时,不需要使用@ResponseBody

标签: java spring spring-boot


【解决方案1】:

现在,当您在 Model 类上使用 @Repository 时,您正在注册两个不同类型的 Model bean,您不应该这样做,因为这是用于数据库存储库的。如果您从 Model 中删除 @Repository,您将只有一个 bean 定义,因此将正确的定义注入您的控制器:

// @Repository remove this, should not be used here
public class Model {
    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Model(String name) {
        super();
        this.name = name;
    }

    public Model() {
        super();
        // TODO Auto-generated constructor stub
    }
}

它与@Primary 一起使用的原因是,您随后定义了Model 类型的所有bean 的顺序重要性。

【讨论】:

  • 我有一个问题,如果我不删除 @Repository,为什么 spring 不会为模型的多个 bean 提供错误。
  • 您可以根据需要使用 Spring 定义任意数量的给定类型的 bean。如果定义一个类型的多个 bean,Spring 不会抛出错误,因为这是一个常见的用例,例如为您调用的每个远程系统设置多个RestTemplate,并按名称或使用@Qualifier("restTemplateOne") 将它们分开。我真的可以推荐阅读 Spring IoC 容器文档:docs.spring.io/spring/docs/current/spring-framework-reference/…
  • @rieckpil 但是当Model bean 都没有用@Primary 注释时,Spring 不应该在自动装配中抛出异常吗?我在想 Spring 不应该能够决定选择哪个候选 bean。为什么OP在添加@Primary之前得到了成功的输出?
  • 如果你不使用@Primary并且有两个相同类型的bean,你可以使用它们的bean名称来引用它们,例如modelBmodelA 和 Spring 会为你注入正确的。
  • @rieckpil 哦,好吧,所以@Repository class Model 将创建一个名为model 的bean,它与带有@Autowired 注释的变量名称匹配,这就是Spring 选择它的原因。明白了,谢谢。
【解决方案2】:

@Repository 表示您正在 bean factory 中注入类型为 repository 的 bean,此外,当您还添加 @Bean 注释时,它成为第二个 bean,因此它在这两个 bean 之间创建了一个重要问题,当您添加@Primary 它重视你的 @Bean 注释 bean。

【讨论】:

    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2019-09-18
    • 2019-12-18
    • 2021-08-11
    相关资源
    最近更新 更多