Skip to content

Commit 6b7f3fd

Browse files
committed
No external locking for singleton advice/aspect beans
Issue: SPR-14324 (cherry picked from commit e18e7ec)
1 parent 4ce0e6b commit 6b7f3fd

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/BeanFactoryAspectInstanceFactory.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,19 @@ public AspectMetadata getAspectMetadata() {
9393
}
9494

9595
public Object getAspectCreationMutex() {
96-
return (this.beanFactory instanceof ConfigurableBeanFactory ?
97-
((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex() : this);
96+
if (this.beanFactory != null) {
97+
if (this.beanFactory.isSingleton(name)) {
98+
// Rely on singleton semantics provided by the factory -> no local lock.
99+
return null;
100+
}
101+
else if (this.beanFactory instanceof ConfigurableBeanFactory) {
102+
// No singleton guarantees from the factory -> let's lock locally but
103+
// reuse the factory's singleton lock, just in case a lazy dependency
104+
// of our advice bean happens to trigger the singleton lock implicitly...
105+
return ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
106+
}
107+
}
108+
return this;
98109
}
99110

100111
/**

spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/LazySingletonAspectInstanceFactoryDecorator.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,14 @@ public Object getAspectInstance() {
4949
if (this.maaif instanceof BeanFactoryAspectInstanceFactory) {
5050
mutex = ((BeanFactoryAspectInstanceFactory) this.maaif).getAspectCreationMutex();
5151
}
52-
synchronized (mutex) {
53-
if (this.materialized == null) {
54-
this.materialized = this.maaif.getAspectInstance();
52+
if (mutex == null) {
53+
this.materialized = this.maaif.getAspectInstance();
54+
}
55+
else {
56+
synchronized (mutex) {
57+
if (this.materialized == null) {
58+
this.materialized = this.maaif.getAspectInstance();
59+
}
5560
}
5661
}
5762
}

spring-aop/src/main/java/org/springframework/aop/support/AbstractBeanFactoryPointcutAdvisor.java

+22-6
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
4646

4747
private BeanFactory beanFactory;
4848

49-
private transient Advice advice;
49+
private transient volatile Advice advice;
5050

5151
private transient volatile Object adviceMonitor = new Object();
5252

@@ -98,12 +98,28 @@ public void setAdvice(Advice advice) {
9898

9999
@Override
100100
public Advice getAdvice() {
101-
synchronized (this.adviceMonitor) {
102-
if (this.advice == null && this.adviceBeanName != null) {
103-
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
104-
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
101+
Advice advice = this.advice;
102+
if (advice != null || this.adviceBeanName == null) {
103+
return advice;
104+
}
105+
106+
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
107+
if (this.beanFactory.isSingleton(this.adviceBeanName)) {
108+
// Rely on singleton semantics provided by the factory.
109+
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
110+
this.advice = advice;
111+
return advice;
112+
}
113+
else {
114+
// No singleton guarantees from the factory -> let's lock locally but
115+
// reuse the factory's singleton lock, just in case a lazy dependency
116+
// of our advice bean happens to trigger the singleton lock implicitly...
117+
synchronized (this.adviceMonitor) {
118+
if (this.advice == null) {
119+
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
120+
}
121+
return this.advice;
105122
}
106-
return this.advice;
107123
}
108124
}
109125

0 commit comments

Comments
 (0)