【问题标题】:Prototype scope bean in controller returns the same instance - Spring Boot控制器中的原型范围 bean 返回相同的实例 - Spring Boot
【发布时间】:2019-07-28 22:23:43
【问题描述】:

我有一个控制器,定义如下:

@RestController
public class DemoController {

    @Autowired
    PrototypeBean proto;

    @Autowired
    SingletonBean single;

    @GetMapping("/test")
    public String test() {
        System.out.println(proto.hashCode() + " "+ single.hashCode());
        System.out.println(proto.getCounter());
        return "Hello World";
    }
}

我已经定义了原型bean如下:

@Component
@Scope(value= ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PrototypeBean {
    static int i = 0;

    public int getCounter() {
        return ++i;
    }
}

每次我点击http://localhost:8080/test 我得到相同的实例,并且计数器每次都会递增。 如何确保每次都能获得新实例? 此外,我想知道为什么即使我已将 bean 的范围声明为 Prototype,我也没有获得新实例。

【问题讨论】:

    标签: java spring spring-boot spring-mvc oop


    【解决方案1】:

    您已将DemoController 声明为@RestController,因此它是一个具有单例范围的bean。这意味着它被创建一次,PrototypeBean 也只被注入一次。这就是为什么每个请求都有相同的对象。

    要查看原型如何工作,您必须将 bean 注入其他 bean。这意味着,拥有两个@Components,都自动装配PrototypeBeanPrototypeBeans 实例将在两者中有所不同。

    【讨论】:

      【解决方案2】:

      如果您的目标是每次调用 test() 方法时获取 PrototypeBean 的新实例,请执行 BeanFactory beanFactory@Autowired,删除 PrototypeBean 的全局类字段,并在方法 @987654326 内@,检索PrototypeBean 喜欢:

      PrototypeBean proto = beanFactory.getBean(PrototypeBean.class);
      

      【讨论】:

        【解决方案3】:

        首先,static 变量与类关联而不是与实例关联。删除静态变量。还要添加@Lazy 注解。 像这样的

        @RestController
        public class DemoController {
        
            @Autowired
            @Lazy
            PrototypeBean proto;
        
            @Autowired
            SingletonBean single;
        
            @GetMapping("/test")
            public String test() {
                System.out.println(proto.hashCode() + " "+ single.hashCode());
                System.out.println(proto.getCounter());
                return "Hello World";
            }
        }
        
        @Component
        @Scope(value= ConfigurableBeanFactory.SCOPE_PROTOTYPE)
        public class PrototypeBean {
            int i = 0;
        
            public int getCounter() {
                return ++i;
            }
        }
        

        【讨论】:

          【解决方案4】:

          您要实现的目标是使用 SCOPE_REQUEST(每个 http 请求的新实例)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-06-14
            • 1970-01-01
            • 2011-05-06
            • 1970-01-01
            • 2012-01-22
            • 2013-02-09
            • 1970-01-01
            • 2012-03-28
            相关资源
            最近更新 更多