Not sure if this is a code review or questions on how Spring Boot operates regarding @Service
components with many inbound requests. If it is a question I can certainly re-post in StackExchange > Code Reviews? We basically have the following pattern in Spring Boot :
- Spring Boot application
- RESTful controllers that process
List<DocumentMetadata>
objects - RESTful controller uses a Data Management
@Service
to handle fetching and sorting ofocumentMetadata
objects - Data Management
@Service
uses a Custom sorting@Service
to do the sorting of thesedocumentMetadata
objects
Narrative : Essentially a RESTful endpoint will return a List<DocumentMetadata>
objects (List of objects if you will) as a ResponseEntity
. The custom sorting is implemented as an @Service
with a method for the sort()
. My understanding is that Spring Boot will create a "singleton" instance of the Custom sorting @Service
utility. I've googled a number of questions on Spring Boot @Service
and lifecycle, and found the following. This posting, which described some usage that led to my questions/review, Should service layer classes be singletons? , especially this comment "Also, mutable state within a Spring singleton is absolutely fine, you just need to be aware of what operations can be done on that shared state – skaffman". I also read thru this posting, Can Spring Boot application handle multiple requests simultaneously?, which seems to suggest we are ok since the object we are creating, sorting and returning is created within the @GetMapping
and passed into the Service component layers, i.e. it's not shared.
My Questions :
- Is this even the right way to design a RESTful stack? Specifically the Utility classes we need...should they be done as
@Service
or asPOJO
classes that get used within the Data Management@Service
layer. - In a multi-request situation where 10-100 requests are hitting the RESTful endpoint at once, what happens to the Custom Sorting utility
@Service
and thesort()
method? Does thesort()
method service each request sequentially? or in parallel in different threads? - Is every request using the same sort method, i.e. the Custom Sorting utility
@Service
is a "singleton" so how is thesort()
method utilized? - If the sort() method is truly single, could 1 user potentially end up with another user's sorted List if both Users hit the method simultaneously? Or does Spring Boot simply process the inbound requests in sequence or in their own threads and avoid any mixing.
Code snippets : I removed much of the code for brevity.
@RestController
@RequestMapping(value = "/search")
@CrossOrigin(origins = "*")
@Slf4j
public class SearchController {
// @Service for Data handling...
@Autowired
private DataManagementService dataManagementService;
@GetMapping(value="/viewable-documents")
public SearchResponse getExternallyViewableDocuments(@RequestParam(required = false) Map<String, String> queryParams) {
logger.debug("getViewableDocuments is called with {}", queryParams);
SearchResponse searchResponse = new SearchResponse();
// ENDPOINT : Calls the Data Management handling @Service...
SearchResponse response = dataManagementService.getDocuments(queryParams);
}
}
@Service
public class DataManagementServiceImpl implements DataManagementService {
// CUSTOM SORT UTILITY : Autowired with setter...
private DocumentSortUtility documentSortUtility;
@Autowired
public void setDocumentSortUtility(DocumentSortUtility setValue) {
this.documentSortUtility = setValue;
}
@Override
public SearchResponse getDocuments(Map<String, String> request) {
if (request.get("sort") != null && request.get("sort").equals("true")) {
// SORT : Call the custom sort...
return serviceImpl.populateResponse(this.documentSortUtility.sort(response));
} else {
return serviceImpl.populateResponse(response);
}
}
}
@Service
public class DocumentSortUtility {
public List<DocumentMetadata> sort(List<DocumentMetadata> documentMetadataList) {
log.debug("Un Sorted:"+documentMetadataList);
// Do custom sort of documentMetadataList and place in retList...
log.debug("Sorted:"+retList);
return retList;
}
}
I have confirmed in the code that there are no "shared" mutable objects being maintained/managed in the @Service
layers. The only objects being modified and/or created are done within the methods of the @Service
layers.
Thx in advance...