Search code examples
springspring-mvcdependency-injectionspring-bootspring-ioc

How to use Session Scoped Component in Controller


Count.java:

@Component
@Scope(value = "session",proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Count {
    Integer i;
    public Count() {
        this.i = 0;
    }

Controller:

@Controller
public class GreetingController {
    @Autowired private Count count;
    @RequestMapping("/greeting")
    public String greetingForm(Model model) {
        if(count.i == null) i == 0;
        else i++;
        model.addAttribute("count",String.valueOf(count.i));
        return "greeting";
    }
}

But every i run this controller (/greeting), it always increase the i even when I close the browser, so how can i use this Session Scoped Component in Singleton Controller?


Solution

  • The proxy only intercepts method calls. In your case the following happens:

    @Autowired private Count count;
    

    Creates a proxy that looks like an instance of count and therefore also has an i field. But since the proxy is not the real thing, the Count constructor is not called and iremains uninitialized. That's why you always get null.

    Now let's introduce a getter:

    class Count {
      ...
      public Integer getI() {
        return i;
      }
    

    When you invoke getI() the proxy first checks if there is an instance of the Count bean for the current session. If there is none, one is created. This also means that the Count constructor is called and i is now initalized. Then the proxy delegates the call to the bean's getI() that will return the value of i.