Skip to content

Commit f6024c2

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

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,19 @@ public AspectMetadata getAspectMetadata() {
9292
}
9393

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

99110
/**

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,14 @@ public Object getAspectInstance() {
4848
if (this.maaif instanceof BeanFactoryAspectInstanceFactory) {
4949
mutex = ((BeanFactoryAspectInstanceFactory) this.maaif).getAspectCreationMutex();
5050
}
51-
synchronized (mutex) {
52-
if (this.materialized == null) {
53-
this.materialized = this.maaif.getAspectInstance();
51+
if (mutex == null) {
52+
this.materialized = this.maaif.getAspectInstance();
53+
}
54+
else {
55+
synchronized (mutex) {
56+
if (this.materialized == null) {
57+
this.materialized = this.maaif.getAspectInstance();
58+
}
5459
}
5560
}
5661
}

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

Lines changed: 22 additions & 6 deletions
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

@@ -96,12 +96,28 @@ public void setAdvice(Advice advice) {
9696
}
9797

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

0 commit comments

Comments
 (0)