<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=david@bluesunrise.com" rel="nofollow">David Sean Taylor</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-3426?redirect=false" rel="nofollow">SPR-3426</a></strong> and commented</p>
<p dir="auto">please also see:</p>
<p dir="auto"><a href="http://issues.apache.org/jira/browse/JS2-689" rel="nofollow">http://issues.apache.org/jira/browse/JS2-689</a></p>
<p dir="auto">I know the contention is occurring in Java JDK code, not in Spring itself.<br>
I would like to suggest that Spring provides an improvement: an alternative implementation for multithreaded applications</p>
<p dir="auto">Pasted in issue from Apache JIRA system:</p>
<p dir="auto">It appears that Spring prototype (non-singleton) bean factory creations cause synchronization contention issues under load.<br>
The NavigationalState and PortalURL beans are created several times per request.<br>
Under load with JMeter tests, the synchronization of Java Bean support code (in the JDK), called by Spring's bean factory, was causing severe performance degradation.<br>
Removing this bottleneck improved performance by 5X.<br>
I've attached the Java source from the package java.beans. I believe its these synchronized methods of the java.beans.PropertyEditorManager class that are causing the contention:</p>
<p dir="auto">private static synchronized void initialize() {<br>
private static synchronized void load(Class targetType, String name) {</p>
<p dir="auto">See attached screenshot for performance results before and after removal of prototypes (replaced by constructors).<br>
Using a 4 processor CPU really brings the contention issue to the forefront.</p>
<p dir="auto">When we have hundreds of requests active, there are over 90 blocked threads in the findEditor stack frame:</p>
<p dir="auto">Thread t@98: (state = BLOCKED)</p>
<ul dir="auto">
<li>java.beans.PropertyEditorManager.findEditor(java.lang.Class) <code class="notranslate">@bci</code>=0, line=75 (Compiled frame; information may be imprecise)</li>
<li>org.springframework.beans.TypeConverterDelegate.convertIfNecessary(java.lang.String, java.lang.Object, java.lang.Object, java.lang.Class, java.beans.PropertyDescriptor, org.springframework.core.MethodParameter) <code class="notranslate">@bci</code>=115, line=174 (Compiled frame)</li>
<li>org.springframework.beans.TypeConverterDelegate.convertIfNecessary(java.lang.Object, java.lang.Class, org.springframework.core.MethodParameter) <code class="notranslate">@bci</code>=7, line=95 (Compiled frame)</li>
<li>org.springframework.beans.factory.support.AbstractBeanFactory.doTypeConversionIfNecessary(org.springframework.beans.TypeConverter, java.lang.Object, java.lang.Class, org.springframework.core.MethodParameter) <code class="notranslate">@bci</code>=47, line=761 (Compiled frame)</li>
<li>org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition) <code class="notranslate">@bci</code>=191, line=126 (Compiled frame)</li>
<li>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition) <code class="notranslate">@bci</code>=12, line=683 (Compiled frame)</li>
<li>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[]) <code class="notranslate">@bci</code>=224, line=380 (Compiled frame)</li>
<li>org.springframework.beans.factory.support.AbstractBeanFactory.getBean(java.lang.String, java.lang.Class, java.lang.Object[]) <code class="notranslate">@bci</code>=362, line=264 (Compiled frame)</li>
<li>org.springframework.beans.factory.support.AbstractBeanFactory.getBean(java.lang.String, java.lang.Class) <code class="notranslate">@bci</code>=4, line=160 (Compiled frame)</li>
<li>org.apache.jetspeed.container.state.impl.JetspeedNavigationalStateComponent.createURL(javax.servlet.http.HttpServletRequest, java.lang.String) <code class="notranslate">@bci</code>=29, line=131 (Compiled frame)</li>
<li>org.apache.jetspeed.pipeline.JetspeedPipeline$Invocation.invokeNex</li>
</ul>
<p dir="auto">My first solution was to remove the Spring prototype code and replace it with straight constructors (replacing commented code below):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="public PortalURL createURL( HttpServletRequest request, String characterEncoding )
{
    //PortalURL url = (PortalURL) beanFactory.getBean(urlBeanName, PortalURL.class); &lt;--- **** used to be one line prototype creation, commented out....
    NavigationalStateCodec codec = (NavigationalStateCodec)beanFactory.getBean(&quot;NavigationalStateCodec&quot;);
    JetspeedCache cache = (JetspeedCache)beanFactory.getBean(&quot;portletContentCache&quot;);
    NavigationalState navState = new SessionFullNavigationalState( codec, cache);
    PortalContext context = (PortalContext)beanFactory.getBean(&quot;PortalContext&quot;);
    PortalURL url = new PathInfoEncodingPortalURL(navState, context);"><pre class="notranslate"><code class="notranslate">public PortalURL createURL( HttpServletRequest request, String characterEncoding )
{
    //PortalURL url = (PortalURL) beanFactory.getBean(urlBeanName, PortalURL.class); &lt;--- **** used to be one line prototype creation, commented out....
    NavigationalStateCodec codec = (NavigationalStateCodec)beanFactory.getBean("NavigationalStateCodec");
    JetspeedCache cache = (JetspeedCache)beanFactory.getBean("portletContentCache");
    NavigationalState navState = new SessionFullNavigationalState( codec, cache);
    PortalContext context = (PortalContext)beanFactory.getBean("PortalContext");
    PortalURL url = new PathInfoEncodingPortalURL(navState, context);
</code></pre></div>
<p dir="auto">Perhaps it could be configured as:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="public PortalURL createURL( HttpServletRequest request, String characterEncoding )
{
    if (useSpringToWireBeans)
    {
     PortalURL url = (PortalURL) beanFactory.getBean(urlBeanName, PortalURL.class);"><pre class="notranslate"><code class="notranslate">public PortalURL createURL( HttpServletRequest request, String characterEncoding )
{
    if (useSpringToWireBeans)
    {
     PortalURL url = (PortalURL) beanFactory.getBean(urlBeanName, PortalURL.class);
</code></pre></div>
<p dir="auto">}<br>
else<br>
{<br>
NavigationalStateCodec codec = (NavigationalStateCodec)beanFactory.getBean("NavigationalStateCodec");<br>
JetspeedCache cache = (JetspeedCache)beanFactory.getBean("portletContentCache");<br>
NavigationalState navState = new SessionFullNavigationalState( codec, cache);<br>
PortalContext context = (PortalContext)beanFactory.getBean("PortalContext");<br>
PortalURL url = new PathInfoEncodingPortalURL(navState, context);</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 2.0 final</p>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398074080" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/7667" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/7667/hovercard" href="https://github.com/spring-projects/spring-framework/issues/7667">#7667</a> Spring performance is insufficient for intensive work at short scopes (<em><strong>"duplicates"</strong></em>)</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398076947" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/8039" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/8039/hovercard" href="https://github.com/spring-projects/spring-framework/issues/8039">#8039</a> Improve performance of AbstractBeanFactory for high-concurrent-load applications</li>
</ul>
<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=rstoya05-aop" rel="nofollow">Rossen Stoyanchev</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-8410?redirect=false" rel="nofollow">SPR-8410</a></strong> and commented</p>
<p dir="auto">The <code class="notranslate">ContentNegotiatingViewResolver</code> provides a range of options for configuring content negotiation based on the 'Accept' header, by path extension, or by request parameter. However when writing to the response via <code class="notranslate">@ResponseBody</code> only the 'Accept' header is used (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398107200" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/12175" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/12175/hovercard" href="https://github.com/spring-projects/spring-framework/issues/12175">#12175</a>). Furthermore, it's not possible to combine all options in the request mapping of a single method (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398100331" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/11163" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/11163/hovercard" href="https://github.com/spring-projects/spring-framework/issues/11163">#11163</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398108565" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/12378" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/12378/hovercard" href="https://github.com/spring-projects/spring-framework/issues/12378">#12378</a>).</p>
<p dir="auto">This is an umbrella ticket to improve how content negotiation options are configured and to equalize the choices throughout request mappings, <code class="notranslate">@ResponseBody</code> methods, and <code class="notranslate">ContentNegotiatingViewResolver</code>.</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 3.1 M1</p>
<p dir="auto"><strong>Sub-tasks:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398107985" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/12288" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/12288/hovercard" href="https://github.com/spring-projects/spring-framework/issues/12288">#12288</a> Allow valid file extension paths for content negotiation to be specified</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398112803" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/13064" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/13064/hovercard" href="https://github.com/spring-projects/spring-framework/issues/13064">#13064</a> Introduce ContentNegotiationStrategy abstraction</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398112806" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/13065" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/13065/hovercard" href="https://github.com/spring-projects/spring-framework/issues/13065">#13065</a> Enhance "produces" condition to use the new ContentNegotiationManager type</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398112817" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/13066" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/13066/hovercard" href="https://github.com/spring-projects/spring-framework/issues/13066">#13066</a> Enhance RequestResponseBodyMethodProcessor and HttpEntityMethodProcessor to use new the ContentNegotiationManager type</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398112820" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/13067" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/13067/hovercard" href="https://github.com/spring-projects/spring-framework/issues/13067">#13067</a> Enhance ContentNegotiatingViewResolver to use the new ContentNegotiationManager type</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398112821" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/13068" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/13068/hovercard" href="https://github.com/spring-projects/spring-framework/issues/13068">#13068</a> Update the MVC Java config and the MVC namespace to support content negotiation options</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398113149" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/13120" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/13120/hovercard" href="https://github.com/spring-projects/spring-framework/issues/13120">#13120</a> Configure PatternsRequestCondition with information that allows it to do a smart suffix pattern match</li>
</ul>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398113614" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/13190" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/13190/hovercard" href="https://github.com/spring-projects/spring-framework/issues/13190">#13190</a> Spring MVC - Ability to use a Converter based on the Path Extension instead of Accep Header. (<em><strong>"is duplicated by"</strong></em>)</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398114213" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/13282" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/13282/hovercard" href="https://github.com/spring-projects/spring-framework/issues/13282">#13282</a> Allow customization of ContentNegotiatingViewResolver by making some of its methods protected</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398117500" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/13791" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/13791/hovercard" href="https://github.com/spring-projects/spring-framework/issues/13791">#13791</a> Add extension element to Spring Web MVC <code class="notranslate">@RequestMapping</code> annotation</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398103877" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/11658" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/11658/hovercard" href="https://github.com/spring-projects/spring-framework/issues/11658">#11658</a> Add content-negotiation to RequestBody and ResponseBody processing (<em><strong>"supersedes"</strong></em>)</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398100331" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/11163" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/11163/hovercard" href="https://github.com/spring-projects/spring-framework/issues/11163">#11163</a> <code class="notranslate">@RequestMapping</code> should support accept header and url extension (<em><strong>"supersedes"</strong></em>)</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398108565" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/12378" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/12378/hovercard" href="https://github.com/spring-projects/spring-framework/issues/12378">#12378</a> <code class="notranslate">@RequestMapping</code> should support alternative between a header and a url extension (<em><strong>"supersedes"</strong></em>)</li>
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398107200" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/12175" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/12175/hovercard" href="https://github.com/spring-projects/spring-framework/issues/12175">#12175</a> Introduce request parameter based content negotiation for ResponseBody / HttpMessageConverter approach (<em><strong>"supersedes"</strong></em>)</li>
</ul>
<p dir="auto">6 votes, 9 watchers</p>