Skip to content

Commit 50253f6

Browse files
committed
Quick access to volatile field (full synchronization only for lazy init)
Issue: SPR-16570
1 parent 139dc1d commit 50253f6

File tree

2 files changed

+40
-23
lines changed

2 files changed

+40
-23
lines changed

spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -60,7 +60,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
6060
private String targetBeanName;
6161

6262
/** Class of the target */
63-
private Class<?> targetClass;
63+
private volatile Class<?> targetClass;
6464

6565
/**
6666
* BeanFactory that owns this TargetSource. We need to hold onto this
@@ -120,19 +120,28 @@ public BeanFactory getBeanFactory() {
120120

121121

122122
@Override
123-
public synchronized Class<?> getTargetClass() {
124-
if (this.targetClass == null && this.beanFactory != null) {
125-
// Determine type of the target bean.
126-
this.targetClass = this.beanFactory.getType(this.targetBeanName);
127-
if (this.targetClass == null) {
128-
if (logger.isTraceEnabled()) {
129-
logger.trace("Getting bean with name '" + this.targetBeanName + "' in order to determine type");
123+
public Class<?> getTargetClass() {
124+
Class<?> targetClass = this.targetClass;
125+
if (targetClass != null) {
126+
return targetClass;
127+
}
128+
synchronized (this) {
129+
// Full check within synchronization, entering the BeanFactory interaction algorithm only once...
130+
targetClass = this.targetClass;
131+
if (targetClass == null && this.beanFactory != null) {
132+
// Determine type of the target bean.
133+
targetClass = this.beanFactory.getType(this.targetBeanName);
134+
if (targetClass == null) {
135+
if (logger.isTraceEnabled()) {
136+
logger.trace("Getting bean with name '" + this.targetBeanName + "' for type determination");
137+
}
138+
Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
139+
targetClass = beanInstance.getClass();
130140
}
131-
Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
132-
this.targetClass = beanInstance.getClass();
141+
this.targetClass = targetClass;
133142
}
143+
return targetClass;
134144
}
135-
return this.targetClass;
136145
}
137146

138147
@Override

spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcAccessor.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -46,7 +46,7 @@ public abstract class JdbcAccessor implements InitializingBean {
4646
private DataSource dataSource;
4747

4848
@Nullable
49-
private SQLExceptionTranslator exceptionTranslator;
49+
private volatile SQLExceptionTranslator exceptionTranslator;
5050

5151
private boolean lazyInit = true;
5252

@@ -109,17 +109,25 @@ public void setExceptionTranslator(SQLExceptionTranslator exceptionTranslator) {
109109
* {@link SQLStateSQLExceptionTranslator} in case of no DataSource.
110110
* @see #getDataSource()
111111
*/
112-
public synchronized SQLExceptionTranslator getExceptionTranslator() {
113-
if (this.exceptionTranslator == null) {
114-
DataSource dataSource = getDataSource();
115-
if (dataSource != null) {
116-
this.exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
117-
}
118-
else {
119-
this.exceptionTranslator = new SQLStateSQLExceptionTranslator();
112+
public SQLExceptionTranslator getExceptionTranslator() {
113+
SQLExceptionTranslator exceptionTranslator = this.exceptionTranslator;
114+
if (exceptionTranslator != null) {
115+
return exceptionTranslator;
116+
}
117+
synchronized (this) {
118+
exceptionTranslator = this.exceptionTranslator;
119+
if (exceptionTranslator == null) {
120+
DataSource dataSource = getDataSource();
121+
if (dataSource != null) {
122+
exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
123+
}
124+
else {
125+
exceptionTranslator = new SQLStateSQLExceptionTranslator();
126+
}
127+
this.exceptionTranslator = exceptionTranslator;
120128
}
129+
return exceptionTranslator;
121130
}
122-
return this.exceptionTranslator;
123131
}
124132

125133
/**

0 commit comments

Comments
 (0)