0

In the simple spring rest controller class below, should the @RequestBody model object/component AUser be singleton or prototype. I want to check this because, each request is served by a separate thread with different values for AUser, so if the AUser class is of default Singleton type, won't the requests from various threads hitting simultaneously override each others data.

@RestController
@Component
public class ExampleController {           
    @PostMapping("/hello")
    public String sayHello(@RequestBody AUser user) {
        return "hello " + user.userName + " from " + user.userCity;
    }
}   

@Component
class AUser {
   public String userName;
   public String userCity;    
}
joven
  • 371
  • 1
  • 6
  • 17
  • Making them Thread safe will answer your question. Refer this : [Are Spring Beans Thread Safe](https://stackoverflow.com/questions/15745140/are-spring-objects-thread-safe) – Ragnar921 May 22 '21 at 23:46

2 Answers2

3

As described in the documentation1 and documentation2 spring uses HttpMessageConverter to convert the input into an Object which later you can use in the controller method.

For Json type of messages the HttpMessageConverter implementations that are embedded in spring framework can be found under the package org.springframework.http.converter.json. Some of those converters use the Jackson library other the Gson library and some some more custom.

Point is that all those libraries (Jackson, Gson) don't create Spring beans. They just call the constructor of the class that you expect to be instantiated and then use the http message body to fill the fields of the object that was instantiated. So in the end the object that they create is a simple java instance. Not a proxy instance which is handled by spring and belongs to the spring context.

You can go and check for example ObjectMapper of Jackson library and see how it works.

Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47
  • 1
    this answers - `They just call the constructor of the class that you expect to be instantiated and then use the http message body to fill the fields of the object that was instantiated.` +1. – joven May 23 '21 at 09:01
1

There’s no need for AUser, or any other type that is used as a @RequestBody parameter, to be a bean.

When Spring MVC is handling the request prior to calling sayHello, a new instance of AUser will be created and populated using the request’s body. This is done using an HttpMessageConverter, as described in the Spring Framework reference documentation. sayHello will then be called with an AUser instance that is specific to that invocation of the method.

Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242
  • that great to hear. `a new instance of AUser will be created` +1. So the explicit declaration using @Component on the `AUser` bean will be ignored (as being a singleton bean). Can you point to any documentation so i can share the same with my team members. – joven May 23 '21 at 07:04
  • if there is a doc reference, i can potentially accept this Answer. – joven May 23 '21 at 07:05
  • I’ve added a link to the reference documentation. You could, of course, observe the behaviour for yourself. Remove `@Component` from `AUser` and your controller method will still work. You could also place a breakpoint in its constructor and see instances being created during HTTP message conversion. – Andy Wilkinson May 23 '21 at 09:29
  • great and tx. So what i get is - irrespective of the @Request/ResponeBody classes annotated with @Component etc, spring does not manage these as Beans. – joven May 23 '21 at 09:39