No external locking for singleton advice/aspect beans
Issue: SPR-14324
(cherry picked from commit 5ac5ec1)
This commit is contained in:
@@ -97,8 +97,19 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getAspectCreationMutex() {
|
public Object getAspectCreationMutex() {
|
||||||
return (this.beanFactory instanceof ConfigurableBeanFactory ?
|
if (this.beanFactory != null) {
|
||||||
((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex() : this);
|
if (this.beanFactory.isSingleton(name)) {
|
||||||
|
// Rely on singleton semantics provided by the factory -> no local lock.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (this.beanFactory instanceof ConfigurableBeanFactory) {
|
||||||
|
// No singleton guarantees from the factory -> let's lock locally but
|
||||||
|
// reuse the factory's singleton lock, just in case a lazy dependency
|
||||||
|
// of our advice bean happens to trigger the singleton lock implicitly...
|
||||||
|
return ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -48,9 +48,15 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
|||||||
@Override
|
@Override
|
||||||
public Object getAspectInstance() {
|
public Object getAspectInstance() {
|
||||||
if (this.materialized == null) {
|
if (this.materialized == null) {
|
||||||
synchronized (this.maaif.getAspectCreationMutex()) {
|
Object mutex = this.maaif.getAspectCreationMutex();
|
||||||
if (this.materialized == null) {
|
if (mutex == null) {
|
||||||
this.materialized = this.maaif.getAspectInstance();
|
this.materialized = this.maaif.getAspectInstance();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
synchronized (mutex) {
|
||||||
|
if (this.materialized == null) {
|
||||||
|
this.materialized = this.maaif.getAspectInstance();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactor
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the best possible creation mutex for this factory.
|
* Return the best possible creation mutex for this factory.
|
||||||
* @return the mutex object (never {@code null})
|
* @return the mutex object (may be {@code null} for no mutex to use)
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
*/
|
*/
|
||||||
Object getAspectCreationMutex();
|
Object getAspectCreationMutex();
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
|||||||
|
|
||||||
private BeanFactory beanFactory;
|
private BeanFactory beanFactory;
|
||||||
|
|
||||||
private transient Advice advice;
|
private transient volatile Advice advice;
|
||||||
|
|
||||||
private transient volatile Object adviceMonitor = new Object();
|
private transient volatile Object adviceMonitor = new Object();
|
||||||
|
|
||||||
@@ -98,12 +98,28 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Advice getAdvice() {
|
public Advice getAdvice() {
|
||||||
synchronized (this.adviceMonitor) {
|
Advice advice = this.advice;
|
||||||
if (this.advice == null && this.adviceBeanName != null) {
|
if (advice != null || this.adviceBeanName == null) {
|
||||||
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
|
return advice;
|
||||||
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
|
}
|
||||||
|
|
||||||
|
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
|
||||||
|
if (this.beanFactory.isSingleton(this.adviceBeanName)) {
|
||||||
|
// Rely on singleton semantics provided by the factory.
|
||||||
|
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
|
||||||
|
this.advice = advice;
|
||||||
|
return advice;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No singleton guarantees from the factory -> let's lock locally but
|
||||||
|
// reuse the factory's singleton lock, just in case a lazy dependency
|
||||||
|
// of our advice bean happens to trigger the singleton lock implicitly...
|
||||||
|
synchronized (this.adviceMonitor) {
|
||||||
|
if (this.advice == null) {
|
||||||
|
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
|
||||||
|
}
|
||||||
|
return this.advice;
|
||||||
}
|
}
|
||||||
return this.advice;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user