Skip to content

Commit 750f84c

Browse files
authored
Merge pull request spring-projects#1 from elost/feature/fix-concurrent-post-processors-manipulation
fix concurrent postprocessors manipulation
2 parents 0e7ae19 + 7a262c0 commit 750f84c

File tree

4 files changed

+31
-17
lines changed

4 files changed

+31
-17
lines changed

spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/target/AbstractBeanFactoryBasedTargetSourceCreator.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,7 @@ protected DefaultListableBeanFactory buildInternalBeanFactory(ConfigurableBeanFa
148148

149149
// Filter out BeanPostProcessors that are part of the AOP infrastructure,
150150
// since those are only meant to apply to beans defined in the original factory.
151-
for (Iterator<BeanPostProcessor> it = internalBeanFactory.getBeanPostProcessors().iterator(); it.hasNext();) {
152-
if (it.next() instanceof AopInfrastructureBean) {
153-
it.remove();
154-
}
155-
}
151+
internalBeanFactory.removePostprocessorsOfType(AopInfrastructureBean.class);
156152

157153
return internalBeanFactory;
158154
}

spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, St
429429

430430
@Override
431431
public void destroyBean(Object existingBean) {
432-
new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
432+
new DisposableBeanAdapter(existingBean, getBeanPostProcessorsMutable(), getAccessControlContext()).destroy();
433433
}
434434

435435

spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
145145
private final List<StringValueResolver> embeddedValueResolvers = new LinkedList<StringValueResolver>();
146146

147147
/** BeanPostProcessors to apply in createBean */
148-
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
148+
private final List<BeanPostProcessor> beanPostProcessors = Collections.synchronizedList(new ArrayList<BeanPostProcessor>());
149149

150150
/** Indicates whether any InstantiationAwareBeanPostProcessors have been registered */
151151
private boolean hasInstantiationAwareBeanPostProcessors;
@@ -837,10 +837,32 @@ public int getBeanPostProcessorCount() {
837837
* Return the list of BeanPostProcessors that will get applied
838838
* to beans created with this factory.
839839
*/
840-
public List<BeanPostProcessor> getBeanPostProcessors() {
840+
public List<BeanPostProcessor> getBeanPostProcessorsMutable() {
841841
return this.beanPostProcessors;
842842
}
843843

844+
/**
845+
* Return the list of BeanPostProcessors that will get applied
846+
* to beans created with this factory.
847+
*/
848+
public List<BeanPostProcessor> getBeanPostProcessors() {
849+
synchronized (beanPostProcessors) {
850+
return Collections.unmodifiableList(
851+
new ArrayList<BeanPostProcessor>(this.beanPostProcessors)
852+
);
853+
}
854+
}
855+
856+
public <T> void removePostprocessorsOfType(Class<T> type) {
857+
synchronized (beanPostProcessors) {
858+
for (Iterator<BeanPostProcessor> it = beanPostProcessors.iterator(); it.hasNext(); ) {
859+
if (type.isAssignableFrom(it.next().getClass())) {
860+
it.remove();
861+
}
862+
}
863+
}
864+
}
865+
844866
/**
845867
* Return whether this factory holds a InstantiationAwareBeanPostProcessor
846868
* that will get applied to singleton beans on shutdown.
@@ -1054,7 +1076,7 @@ public void destroyBean(String beanName, Object beanInstance) {
10541076
* @param mbd the merged bean definition
10551077
*/
10561078
protected void destroyBean(String beanName, Object beanInstance, RootBeanDefinition mbd) {
1057-
new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
1079+
new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessorsMutable(), getAccessControlContext()).destroy();
10581080
}
10591081

10601082
@Override
@@ -1625,7 +1647,7 @@ public boolean isBeanNameInUse(String beanName) {
16251647
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
16261648
return (bean != null &&
16271649
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
1628-
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
1650+
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessorsMutable()))));
16291651
}
16301652

16311653
/**
@@ -1648,7 +1670,7 @@ protected void registerDisposableBeanIfNecessary(String beanName, Object bean, R
16481670
// work for the given bean: DestructionAwareBeanPostProcessors,
16491671
// DisposableBean interface, custom destroy method.
16501672
registerDisposableBean(beanName,
1651-
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
1673+
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorsMutable(), acc));
16521674
}
16531675
else {
16541676
// A bean with a custom scope...
@@ -1657,7 +1679,7 @@ protected void registerDisposableBeanIfNecessary(String beanName, Object bean, R
16571679
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
16581680
}
16591681
scope.registerDestructionCallback(beanName,
1660-
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
1682+
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorsMutable(), acc));
16611683
}
16621684
}
16631685
}

spring-context/src/main/java/org/springframework/scripting/support/ScriptFactoryPostProcessor.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,7 @@ public void setBeanFactory(BeanFactory beanFactory) {
219219

220220
// Filter out BeanPostProcessors that are part of the AOP infrastructure,
221221
// since those are only meant to apply to beans defined in the original factory.
222-
for (Iterator<BeanPostProcessor> it = this.scriptBeanFactory.getBeanPostProcessors().iterator(); it.hasNext();) {
223-
if (it.next() instanceof AopInfrastructureBean) {
224-
it.remove();
225-
}
226-
}
222+
this.scriptBeanFactory.removePostprocessorsOfType(AopInfrastructureBean.class);
227223
}
228224

229225
@Override

0 commit comments

Comments
 (0)