Heavily inspired by the PR @MikeRocke, we removed all usage of String.format(…) from hot code paths triggered by ….toString() as it's used in general output a lot.
Before:
Benchmark Mode Cnt Score Error Units
TemplateVariableBenchmark.toString(…) thrpt 3 2803239,270 ± 110258,955 ops/s
After:
Benchmark Mode Cnt Score Error Units
TemplateVariableBenchmark.toString(…) thrpt 3 10753653,459 ± 156684,459 ops/s
The commits for #467 significantly degraded performance as CachingMappingDiscoverer.getParams(Method) doesn't properly cache the result of the call which causes quite expensive, unnecessarily repeated annotation lookups for the very same method. We also avoid the creation of an Optional instance for the sole purpose of a simple null check.
Introduce FormatterFactory to potentially cache the to-String formatting functions and thus avoid repeated evaluation and Function object creation.
We now also avoid the creation of ParamRequestCondition instances if no @RequestParams(params = …) values could be found in the first place.
We now constrain the cache of controller proxy instances to 256 elements using Spring's ConcurrentLruCache to avoid instances created via DummyInvocationUtils.methodOn(Class<?>, Object…). The parameters are part of the cache key and used to expand the type-level mappings. If those vary for each call and a request creates a lot of links (>100000) the memory consumption grows significantly, first and foremost indefinitely.
Using the ThreadLocal will still make sure that the cache is local to a current request, so the proxies can actually be reused as the method invocations used to record the mappings would interfere for concurrent requests otherwise.
Removed obsolete generic parameter on the CacheKey type.
As per the discussion in mamund/hal-forms#88, the list of property types in HAL FORMS is not exhaustive. This means we cannot align them with HTML input types and even more so not drop anything not an HTML input type.
This is now implemented by switching to generic Strings in the HAL FORMS property DTO and directly piping the value originally registered on the affordance into it.
When adding a request parameter template variable and the URI part of the template already contains a request parameter we now automatically turn the variable type into request parameter continuation. That apparently got lost in the move to level 4 URI templates in #1583.
The unwrapping nature of EntityModel.getContent() does not work well with value that would result in an empty object being rendered. We now skip the rendering if failing for empty beans is disabled.
We now skip the registration of the default media type if no hypermedia types are activated in the first place. We previously assumed there'd be at least one media type configuration registered.
If a parameter array is given to MethodLinkBuilderFactory.linkTo(…) methods, we now verify its correct length in correspondence to the method given. If no parameters are given at all, we automatically create a parameter value array of the required length.
We now explicitly set the optimize flag on the ProxyFactory for class based proxies used to create dummy invocation proxies. Still needs the upgrade to Spring Framework 5.3.11 (spring-projects/spring-framework#27439, #1647) to create full effect.
On JDK 17, trying to proxy Object doesn't work anymore. We now simply return the interceptor that would've been applied to the proxy directly and detect that properly in requests to extract the LastInvocationAware instance.