简体   繁体   中英

How to get state of scoped component instance in Spring Boot

I'm looking for a way to take advantage of Spring's Scopes(Prototype or Request) while being able to get the state of these scoped components.

Given the following example

@RestController
@Scope("prototype")
public class FooController {
    private FooService fooService;

    @Autowired
    public FooController(FooService fooService) {
        this.fooService = fooService;
    }

    @RequestMapping("/foo")
    public String foo() {
        fooService.foo();
        return "OK";
    }

    @RequestMapping("/foo/status")
    public int fooStatus() {
        return fooService.getState();
    }
}

@Service
@Scope("prototype")
public class FooService
{
    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    private int state;

    public FooService() { }

    public void foo() {
       //do long work
        state++;
       //do long work
       state++;
    }

}

There is a Controller and a Service, prototyped scoped. How can I get the state of FooService .

The code above isn't working. Maybe something with scopes? status is always zero.

The scenario is to hit /foo/status endpoint and get the status value.

Yes, the answer 0 is expected. Because the spring prototype scope says that you'll get a new instance of the bean, everytime it's requested.

https://www.journaldev.com/21039/spring-bean-scopes

If you use request or prototype scope, it means that with every request new service bean is created with default State variable initialised to 0.

When you first call /foo a new bean of service is created and the State is increased to 2. Next when you call /foo/status new bean with default State 0 is created and returned. Which essentially means that state can't be shared between two requests with these bean scopes. Remove the @scope on the service and controller it should start working fine.

You are creating a business logic component which is recreated on each HTTP request and keeps no track of status.

I guess you have 2 options:

  • remove the scope annotation that recreates your component on each request and change your actual logic / architecture (which is as you say not what you want),
  • define the status variable as static (not recommended). When 2 services run simultaneously your foo method you have to make your incrementation of status thread-save.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM