No external locking for singleton advice/aspect beans
Issue: SPR-14324
(cherry picked from commit e18e7ec)
This commit is contained in:
@@ -93,8 +93,19 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
|
|||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -49,9 +49,14 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
|
|||||||
if (this.maaif instanceof BeanFactoryAspectInstanceFactory) {
|
if (this.maaif instanceof BeanFactoryAspectInstanceFactory) {
|
||||||
mutex = ((BeanFactoryAspectInstanceFactory) this.maaif).getAspectCreationMutex();
|
mutex = ((BeanFactoryAspectInstanceFactory) this.maaif).getAspectCreationMutex();
|
||||||
}
|
}
|
||||||
synchronized (mutex) {
|
if (mutex == null) {
|
||||||
if (this.materialized == null) {
|
this.materialized = this.maaif.getAspectInstance();
|
||||||
this.materialized = this.maaif.getAspectInstance();
|
}
|
||||||
|
else {
|
||||||
|
synchronized (mutex) {
|
||||||
|
if (this.materialized == null) {
|
||||||
|
this.materialized = this.maaif.getAspectInstance();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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