39
39
import java .util .concurrent .Executors ;
40
40
import java .util .concurrent .LinkedBlockingDeque ;
41
41
import java .util .concurrent .Semaphore ;
42
+ import java .util .concurrent .ThreadFactory ;
42
43
import java .util .concurrent .TimeUnit ;
43
44
import java .util .concurrent .TimeoutException ;
44
45
import java .util .concurrent .atomic .AtomicBoolean ;
55
56
import org .springframework .beans .factory .InitializingBean ;
56
57
import org .springframework .jmx .export .annotation .ManagedAttribute ;
57
58
import org .springframework .jmx .export .annotation .ManagedResource ;
59
+ import org .springframework .scheduling .concurrent .CustomizableThreadFactory ;
58
60
import org .springframework .util .Assert ;
59
61
import org .springframework .util .ObjectUtils ;
60
62
import org .springframework .util .StringUtils ;
92
94
* @author Gary Russell
93
95
* @author Artem Bilan
94
96
* @author Steve Powell
97
+ * @author Will Droste
95
98
*/
96
99
@ ManagedResource
97
100
public class CachingConnectionFactory extends AbstractConnectionFactory
98
101
implements InitializingBean , ShutdownListener {
99
102
100
103
private static final int DEFAULT_CHANNEL_CACHE_SIZE = 25 ;
101
104
105
+ private static final String DEFAULT_DEFERRED_POOL_PREFIX = "spring-rabbit-deferred-pool-" ;
106
+
107
+ /**
108
+ * Create a unique ID for the pool.
109
+ */
110
+ private static final AtomicInteger threadPoolId = new AtomicInteger ();
111
+
102
112
private static final Set <String > txStarts = new HashSet <>(Arrays .asList ("basicPublish" , "basicAck" ,
103
113
"basicNack" , "basicReject" ));
104
114
@@ -148,9 +158,6 @@ public enum CacheMode {
148
158
/** Synchronization monitor for the shared Connection. */
149
159
private final Object connectionMonitor = new Object ();
150
160
151
- /** Executor used for deferred close if no explicit executor set. */
152
- private final ExecutorService deferredCloseExecutor = Executors .newCachedThreadPool ();
153
-
154
161
private long channelCheckoutTimeout = 0 ;
155
162
156
163
private CacheMode cacheMode = CacheMode .CHANNEL ;
@@ -172,6 +179,10 @@ public enum CacheMode {
172
179
private volatile boolean active = true ;
173
180
174
181
private volatile boolean initialized ;
182
+ /**
183
+ * Executor used for deferred close if no explicit executor set.
184
+ */
185
+ private ExecutorService deferredCloseExecutor ;
175
186
176
187
private volatile boolean stopped ;
177
188
@@ -764,7 +775,9 @@ public final void destroy() {
764
775
resetConnection ();
765
776
if (getContextStopped ()) {
766
777
this .stopped = true ;
767
- this .deferredCloseExecutor .shutdownNow ();
778
+ if (this .deferredCloseExecutor != null ) {
779
+ this .deferredCloseExecutor .shutdownNow ();
780
+ }
768
781
}
769
782
}
770
783
@@ -910,6 +923,28 @@ private int countOpenConnections() {
910
923
return n ;
911
924
}
912
925
926
+ /**
927
+ * Determine the executor service used to close connections.
928
+ * @return specified executor service otherwise the default one is created and returned.
929
+ * @since 1.7.9
930
+ */
931
+ protected ExecutorService getDeferredCloseExecutor () {
932
+ if (getExecutorService () != null ) {
933
+ return getExecutorService ();
934
+ }
935
+ synchronized (this .connectionMonitor ) {
936
+ if (this .deferredCloseExecutor == null ) {
937
+ final String threadPrefix =
938
+ getBeanName () == null
939
+ ? DEFAULT_DEFERRED_POOL_PREFIX + threadPoolId .incrementAndGet ()
940
+ : getBeanName ();
941
+ ThreadFactory threadPoolFactory = new CustomizableThreadFactory (threadPrefix );
942
+ this .deferredCloseExecutor = Executors .newCachedThreadPool (threadPoolFactory );
943
+ }
944
+ }
945
+ return this .deferredCloseExecutor ;
946
+ }
947
+
913
948
@ Override
914
949
public String toString () {
915
950
return "CachingConnectionFactory [channelCacheSize=" + this .channelCacheSize + ", host=" + getHost ()
@@ -1187,9 +1222,7 @@ private void physicalClose() throws Exception {
1187
1222
}
1188
1223
1189
1224
private void asyncClose () {
1190
- ExecutorService executorService = (getExecutorService () != null
1191
- ? getExecutorService ()
1192
- : CachingConnectionFactory .this .deferredCloseExecutor );
1225
+ ExecutorService executorService = getDeferredCloseExecutor ();
1193
1226
final Channel channel = CachedChannelInvocationHandler .this .target ;
1194
1227
executorService .execute (() -> {
1195
1228
try {
0 commit comments