Issue 1:
Keith Donald opened SPR-7839 and commented

This is effecting the mvc-showcase sample after upgrading from 3.0.4 to 3.0.5.

In the failing scenario, I'm attempting to bind to:

public class JavaBean {

private NestedBean nested;

}

public class NestedBean {

private String foo;

private List<NestedBean> list;

private Map<String, NestedBean> map;

}

(Note: getters and setters have been omitted for brevity)

The actual binding expression is:

http://localhost:8080/mvc-showcase/convert/bean?nested.foo=bar&nested.list[0].foo=baz&nested.map[key].list[0].foo=bip

During binding, the "nested" property is initially null and the expectation is "auto-grow" behavior will kick-in.

The stack trace of the runtime exception that is thrown is:

org.springframework.beans.NullValueInNestedPathException: Invalid property 'nested.map[key]' of bean class [org.springframework.samples.mvc.convert.JavaBean]: Could not determine property type for auto-growing a default value
org.springframework.beans.BeanWrapperImpl.createDefaultPropertyValue(BeanWrapperImpl.java:601)
org.springframework.beans.BeanWrapperImpl.setDefaultValue(BeanWrapperImpl.java:593)
org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:558)
org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:532)
org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:533)
org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:890)
org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:673)
org.springframework.validation.DataBinder.doBind(DataBinder.java:569)
org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:191)
org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:110)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.doBind(AnnotationMethodHandlerAdapter.java:736)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doBind(HandlerMethodInvoker.java:805)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:359)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:171)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.samples.mvc.flash.FlashMapFilter.doFilterInternal(FlashMapFilter.java:33)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

Affects: 3.0.5

Issue Links:

#12370 Regression binding to nested properties on map values with auto-grow ("duplicates")

1 votes, 3 watchers

Issue 2:
Antranig Basman opened SPR-2981* and commented

When making large numbers of instantiations, in particular at short scopes such as within an HTTP request, Spring core performance can become a bottleneck. Note that this appears to be an orthogonal problem to that referred to in #7460 since this affects singleton and non-singleton beans alike, even (and, actually especially) in a single-threaded context. This is suggested also by the fact that this speed test is affected relatively little by the change from Spring 1.2.8 to 2.0.1 (slows by around 4%)

There is a test project in our SVN tagged at https://saffron.caret.cam.ac.uk/svn/projects/TestRSAC/tags/J-ServletUtil-1.2 which demonstrates the issue. A modest-sized container (30 beans with varying numbers of properties from 1 to 13) is fired up in various versions of Spring, and is subjected to repeated cycles of a fetch of the most derived bean followed by a call to destroySingletons(). This stabilises in the region of 8ms per instantiation of the bean set (for these 30 beans, on a fairly modest laptop). This would obviously be an unacceptable per-request overhead if occuring on each HTTP cycle.

It's worth comparing this much lower figure with that of the 6-bean container in #7460 - I think much of the difference lies in the considerably greater number of properties (some of which require conversion) on the beans in this test, which is more representative of a real-world container. For comparison purposes a run with a SINGLE leaf bean instantiates the container in only 22 microseconds, more than 400 times faster - demonstrating that the overhead is really a per-bean one, and strongly penalising beans with larger and more complex property sets.

Profiling suggests that around 30% of the time is being lost in Sun introspection code, and a further 30% in instantiation of BeanWrapperImpl objects, which appear to be fabricated in a complete fresh set for every property set. Synchronisation also seems to be a significant part of the overhead. Even with removal of those first two two sources of overhead, the lag from this test instantation still couldn't be overwhelmingly expected to be <1ms, which is still somewhat dubious.

This is the main reason for development of "RSAC", a lightweight "Spring core" workalike, which sacrifices a good deal of Spring's flexibility (multi-threaded access, dynamic modifications to container heirarchy) in order to focus on the core cases of instantiations of and access to a set of beans bound to a single thread (typically within an HTTP request). Request-scope IoC has proved a big architectural benefit for the coherence and portability of RSF, and it would be marvellous if at some point we could stop maintaining RSAC and have similar capabilities within the Spring core :P - post 2.0 it now seems conceivable that this could become packaged as some new kind of Scope within Spring.

General notes on RSAC at http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=RSAC - the key points are that most of Spring core is implemented (with the notable exceptions of constructor injection and autowiring), and since it relies on genuine Spring core for reading BeanDefinitions it is immune to upgrades in the container file format. RSAC is generally around 50-80x faster at Spring proper at instantiating the TestRSAC context file. Raw numbers follow:

Results (1.8Ghz Pentium M, SpeedStep engaged, JDK 1.4.2, Windows 2000)

Main container (requestscope.xml, 30 beans)

Spring 1.2.8:

1000 instantations in 24695 ms: 24.695ms/instance

10000 instantations in 239705 ms: 23.970ms/instance

Spring 2.0.1: 1000 instantations in 25296 ms: 25.296ms/instance

RSAC 1.2:

1000 instantations in 631 ms: 0.631ms/instance

10000 instantations in 4066 ms: 0.407ms/instance

100000 instantations in 38085 ms: 0.381ms/instance

(SpeedStep disengaged, maximum CPU)

Spring 1.2.8: 1000 instantations in 8232 ms: 8.232ms/instance

RSAC 1.2: 10000 instantations in 1342 ms: 0.134ms/instance

Tiny container (tinyrequestscope.xml, 1 bean, maximum CPU)

Spring 1.2.8: 1000000 instantations in 21701 ms: 0.022ms/instance

RSAC 1.2: 10000000 instantations in 16044 ms: 0.0016ms/instance

Affects: 2.0.1

Issue Links:

#8109 Spring Bean Factory creation of Prototype (non-singleton) beans causes serious performance degradation under load ("is duplicated by")

#7460 Poor performance creating non-singleton beans with many threads

2 votes, 5 watchers