Browse Source
PR gh-25038 introduced regressions in SimpleThreadScope and SimpleTransactionScope in Spring Framework 5.2.7. Specifically, if a thread-scoped or transaction-scoped bean has a dependency on another thread-scoped or transaction-scoped bean, respectively, a ConcurrentModificationException will be thrown on Java 11 or higher. The reason is that Java 11 introduced a check for concurrent modification in java.util.HashMap's computeIfAbsent() implementation, and such a modification can occur when a thread-scoped bean is being created in order to satisfy a dependency of another thread-scoped bean that is currently being created. This commit fixes these regressions by switching from HashMap to ConcurrentHashMap for the instance maps in SimpleThreadScope and SimpleTransactionScope. Closes gh-25618pull/25798/head
4 changed files with 16 additions and 46 deletions
@ -1,51 +1,21 @@
@@ -1,51 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<beans xmlns="http://www.springframework.org/schema/beans" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans |
||||
https://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> |
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> |
||||
|
||||
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"> |
||||
<property name="scopes"> |
||||
<map> |
||||
<entry key="thread"> |
||||
<bean class="org.springframework.context.support.SimpleThreadScope"/> |
||||
<bean class="org.springframework.context.support.SimpleThreadScope" /> |
||||
</entry> |
||||
</map> |
||||
</property> |
||||
</bean> |
||||
|
||||
<bean id="threadScopedObject" class="org.springframework.beans.testfixture.beans.TestBean" scope="thread"/> |
||||
|
||||
<!-- |
||||
<bean id="requestScopedDisposableObject" class="org.springframework.beans.testfixture.beans.DerivedTestBean" scope="request"/> |
||||
|
||||
<bean id="requestScopedFactoryBean" class="org.springframework.beans.testfixture.beans.factory.DummyFactory" scope="request"/> |
||||
|
||||
<bean id="requestScopedObjectCircle1" class="org.springframework.beans.testfixture.beans.TestBean" scope="request"> |
||||
<property name="spouse" ref="requestScopedObjectCircle2"/> |
||||
<bean id="threadScopedObject" class="org.springframework.beans.testfixture.beans.TestBean" scope="thread"> |
||||
<property name="spouse" ref="threadScopedObject2" /> |
||||
</bean> |
||||
|
||||
<bean id="requestScopedObjectCircle2" class="org.springframework.beans.testfixture.beans.TestBean" scope="request"> |
||||
<property name="spouse" ref="requestScopedObjectCircle1"/> |
||||
</bean> |
||||
|
||||
<bean id="requestScopedOuterBean" class="org.springframework.beans.testfixture.beans.DerivedTestBean" scope="request"> |
||||
<property name="name" value="outer"/> |
||||
<property name="spouse"> |
||||
<bean class="org.springframework.beans.testfixture.beans.DerivedTestBean"> |
||||
<property name="name" value="inner"/> |
||||
</bean> |
||||
</property> |
||||
</bean> |
||||
|
||||
<bean id="singletonOuterBean" class="org.springframework.beans.testfixture.beans.DerivedTestBean" lazy-init="true"> |
||||
<property name="name" value="outer"/> |
||||
<property name="spouse"> |
||||
<bean class="org.springframework.beans.testfixture.beans.DerivedTestBean" scope="request"> |
||||
<property name="name" value="inner"/> |
||||
</bean> |
||||
</property> |
||||
</bean> |
||||
<bean id="threadScopedObject2" class="org.springframework.beans.testfixture.beans.TestBean" scope="thread" /> |
||||
|
||||
--> |
||||
</beans> |
||||
|
||||
Loading…
Reference in new issue