Home > OS >  Controllers should be 'stateless', does having a final variable for the service object mak
Controllers should be 'stateless', does having a final variable for the service object mak

Time:11-20

I am following best practices to enhance my codebase for my SpringBoot project and my controller classes conform to all the others but I am unsure if this would constitute statefulness as the service class is not subject to change, would this make it immutable?

Example:

@RestController
@RequestMapping(value = "/users")
public class UserController {

    final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }
}

The userService instance field is set to final and is instantiated in the controller's constructor method, does this mean the controller class breaches this best-practice and is stateful?

Thanks

CodePudding user response:

Dependencies are not contributing to a "state" of the object. For your controllers to do any real work, you have to inject various dependencies (other services). However you should inject this UserService with @Authowired, just declaring it in a constructor may not work (though I'm not 100% sure).

What would be considered a state is some value that is written when processing request. Anything that is constant is not really a state.

The main goal is to have one controller to handle many requests without any risk of them (requests) interfering with each other.

CodePudding user response:

No this does not make the controller stateful. I would consider this the best approach. You could make the UserService field private as well. Constructor injection is preferable to Field injection IMO e.g. https://www.javacodegeeks.com/2019/02/field-setter-constructor-injection.html

CodePudding user response:

The final keyword just enforces that the concrete UserService can't be changed during the life cycle of the UserController instance.

Spring Controllers are Singletons, so there is one instance per class, which means multiple subsequent requests made to the Controller are served by the same instance.

So no, the final keyword does not make your Controller stateful. A dependency to another class to do work does not make the calling class (your Controller) stateful.

Also: the final keyword just makes the variable reference immutable, i.e., your userService property always points to the same UserService instance. However, the UserService instance itself may still be mutable (e.g., if it has state, which can be changed). Since @Service classes are also Singletons in Spring, you may want to make the Service stateless as well.

CodePudding user response:

Your code is perfectly fine. UserService is a dependency of your UserController and not exactly something that would "add" state to your controller.

Having a stateful controller would look like the following:

@RestController
@RequestMapping(value = "/users")
public class UserController {

    final UserService userService;

    private final List<String> requestedUsers = new ArrayList();

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping(value = /{userId})
    @ResponseStatus(HttpStatus.OK)
    public User getUser(@PathVariable long userId) {
        requestedUsers.add(userId);
        return this.userService.getUser(userId);
    }
}

Now you have a mutable property in your controller class: requestedUsers. You change this list every time a GET request is done for a given userId by adding this userId to the list. This would "add" state to your controller because now it includes mutable data that is shared and changed every time there is a request to the controller. Noteworthy is the fact that even having requestedUsers as final changes nothing in terms of the statefulness of your controller. The final keyword just guarantees that the reference of the requestedUsers property does not change, but the actual data structure it points to can be changed (as it is possible with List, to which you can add or remove elements without the need to change its reference).

  • Related