How to use Session Scoped Component in Controller

cdxf picture cdxf · Sep 14, 2016 · Viewed 8.1k times · Source

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?

Answer

a better oliver picture a better oliver · Sep 14, 2016

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.