-
Notifications
You must be signed in to change notification settings - Fork 38.6k
Description
Affects: Spring web 4.2+, 5.x (confirmed, possibly others)
A large, publicly-facing application receives more than 100 request parameters (don't ask) and the growing runtime of ServletRequestDataBinder has exposed an inefficiency: for each parameter, AbstractNestablePropertyAccessor.processLocalProperty() throws an exception, which is caught by AbstractPropertyAccessor.setPropertyValues(). This exception is then discarded because "ignoreUnknown" is true, and life goes on.
Throwing exceptions is an expensive operation because of the need to fill in stack traces (Throwable.fillInStackTrace) and this generates significant wasted effort. Modifying ServletRequestDataBinder.bind() to mark each PropertyValue as optional eliminates this penalty while maintaining the same functional behavior. Custom benchmarking shows a 93% reduction in cpu and clock time (21 vs. 350).
Workarounds are difficult because ServletRequestDataBinder is accessed via a chain of hard-coded references, plus our application uses the subclass ExtendedServletRequestDataBinder. The best option I've found so far is to use a custom bean factory to override the requestMappingHandlerAdapter bean (declared in WebMvcConfigurationSupport.requestMappingHandlerAdapter()) and make a subclass that overrides createDataBinderFactory, etc. "Convoluted" and "ugly" are good descriptions of those solution.