vikas tiwari
vikas tiwari

Reputation: 117

Prototype scope bean in controller returns the same instance - Spring Boot

I have a contoller which is defined as below:

@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";
    }
}

And i have defined prototype bean as below:

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

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

Everytime I hit http://localhost:8080/test I get the same instance and the counter gets incremented everytime. How do I make sure that I get new instance everytime ? Also I want to know why I am not getting new instance even though I have declared the scope of the bean as Prototype.

Upvotes: 0

Views: 2077

Answers (4)

Tamir Adler
Tamir Adler

Reputation: 421

If your goal is to get new instance of PrototypeBean each time the method test() is called, do @Autowired of BeanFactory beanFactory, remove the global class field of PrototypeBean, and inside the method test(), retrieve the PrototypeBean like:

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

Upvotes: 1

Tomasz Jagiełło
Tomasz Jagiełło

Reputation: 854

What you are trying to achieve is done by using SCOPE_REQUEST (new instance for every http request).

Upvotes: 1

witty_arrow
witty_arrow

Reputation: 41

First of all, static variable is associated with class not with instance. Remove the static variable. Also add @Lazy annotation. Something like this

@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;
    }
}

Upvotes: 1

Andronicus
Andronicus

Reputation: 26046

You have declared DemoController as @RestController, so it's a bean with singleton scope. It means it's created once and PrototypeBean is also injected only once. That's why every request you have the same object.

To see how prototype works, you would have to inject the bean into other bean. This means, that having two @Components, both autowiring PrototypeBean, PrototypeBeans instance would differ in both of them.

Upvotes: 1

Related Questions