首页 > 解决方案 > @Autowire vs AplicationContext 注入方式

问题描述

@RestController
@RequestMapping("kafka")
public class KafkaController implements ApplicationContextAware {

    @Autowired
    KafkaConfig config;

    ApplicationContext context;

    @GetMapping("messages")
    public void getMessages() throws InterruptedException {
        System.out.println("Queue name is >>>>>>>>>>>>" + config.getQueueName());
        System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<"+ ((KafkaConfig)context.getBean("kafkaConfigBean")).getQueueName());

当我多次调用该服务时,它在日志"Queue name is >>>>>>>>>>>>"中给出了相同的 queuename 值,但如果我得到它,则会得到不同的值:((KafkaConfig)context.getBean("kafkaConfigBean")).getQueueName()

当我创建 bean 时,我用它Math.random()来产生不同的输出。

    @Bean("kafkaConfigBean")
    @Scope("prototype")
    public KafkaConfig createKafkaBeanConfig() {
        KafkaConfig conf = new KafkaConfig();
        conf.setQueueName("prototype" + String.valueOf(Math.random()));
        return conf;
    }

为什么它通过applicationContext方式产生不同的价值,但在使用@Autowired. 范围“原型”不是意味着每次请求时都创建新的bean。为什么每次调用控制器@Autowire都返回相同的 bean?

谢谢

标签: spring-bootautowired

解决方案


在第一种情况下,您定义了一个KafkaController包含自动装配字段的单例 bean KafkaConfig config;。由于 bean 是一个单例,它只被创建一次,所以它里面的KafkaConfig字段值也只被创建一次。使用同一个控制器发出多个请求使用相同KafkaConfig的值,因此队列名称不会改变。

在第二种情况下,您context.getBean("kafkaConfigBean")显式地调用自己,这导致 Spring 每次调用它时都会创建一个新 bean,因为您已将该 bean 定义为“原型”。按照设计,每次创建它时,它都会计算一个不同的队列名称。

如果您正在创建多个KafkaController对象,则每个对象都将包含不同的KafkaConfig字段值,每个字段值都有不同的队列名称。


推荐阅读