1
1
/*
2
- * Copyright 2002-2019 the original author or authors.
2
+ * Copyright 2002-2021 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
@@ -87,7 +87,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
87
87
private transient Method destroyMethod ;
88
88
89
89
@ Nullable
90
- private List <DestructionAwareBeanPostProcessor > beanPostProcessors ;
90
+ private final List <DestructionAwareBeanPostProcessor > beanPostProcessors ;
91
91
92
92
93
93
/**
@@ -120,14 +120,16 @@ public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition be
120
120
}
121
121
}
122
122
else {
123
- Class <?>[] paramTypes = destroyMethod .getParameterTypes ();
124
- if (paramTypes .length > 1 ) {
125
- throw new BeanDefinitionValidationException ("Method '" + destroyMethodName + "' of bean '" +
126
- beanName + "' has more than one parameter - not supported as destroy method" );
127
- }
128
- else if (paramTypes .length == 1 && boolean .class != paramTypes [0 ]) {
129
- throw new BeanDefinitionValidationException ("Method '" + destroyMethodName + "' of bean '" +
130
- beanName + "' has a non-boolean parameter - not supported as destroy method" );
123
+ if (destroyMethod .getParameterCount () > 0 ) {
124
+ Class <?>[] paramTypes = destroyMethod .getParameterTypes ();
125
+ if (paramTypes .length > 1 ) {
126
+ throw new BeanDefinitionValidationException ("Method '" + destroyMethodName + "' of bean '" +
127
+ beanName + "' has more than one parameter - not supported as destroy method" );
128
+ }
129
+ else if (paramTypes .length == 1 && boolean .class != paramTypes [0 ]) {
130
+ throw new BeanDefinitionValidationException ("Method '" + destroyMethodName + "' of bean '" +
131
+ beanName + "' has a non-boolean parameter - not supported as destroy method" );
132
+ }
131
133
}
132
134
destroyMethod = ClassUtils .getInterfaceMethodIfPossible (destroyMethod );
133
135
}
@@ -169,67 +171,6 @@ private DisposableBeanAdapter(Object bean, String beanName, boolean invokeDispos
169
171
}
170
172
171
173
172
- /**
173
- * If the current value of the given beanDefinition's "destroyMethodName" property is
174
- * {@link AbstractBeanDefinition#INFER_METHOD}, then attempt to infer a destroy method.
175
- * Candidate methods are currently limited to public, no-arg methods named "close" or
176
- * "shutdown" (whether declared locally or inherited). The given BeanDefinition's
177
- * "destroyMethodName" is updated to be null if no such method is found, otherwise set
178
- * to the name of the inferred method. This constant serves as the default for the
179
- * {@code @Bean#destroyMethod} attribute and the value of the constant may also be
180
- * used in XML within the {@code <bean destroy-method="">} or {@code
181
- * <beans default-destroy-method="">} attributes.
182
- * <p>Also processes the {@link java.io.Closeable} and {@link java.lang.AutoCloseable}
183
- * interfaces, reflectively calling the "close" method on implementing beans as well.
184
- */
185
- @ Nullable
186
- private String inferDestroyMethodIfNecessary (Object bean , RootBeanDefinition beanDefinition ) {
187
- String destroyMethodName = beanDefinition .getDestroyMethodName ();
188
- if (AbstractBeanDefinition .INFER_METHOD .equals (destroyMethodName ) ||
189
- (destroyMethodName == null && bean instanceof AutoCloseable )) {
190
- // Only perform destroy method inference or Closeable detection
191
- // in case of the bean not explicitly implementing DisposableBean
192
- if (!(bean instanceof DisposableBean )) {
193
- try {
194
- return bean .getClass ().getMethod (CLOSE_METHOD_NAME ).getName ();
195
- }
196
- catch (NoSuchMethodException ex ) {
197
- try {
198
- return bean .getClass ().getMethod (SHUTDOWN_METHOD_NAME ).getName ();
199
- }
200
- catch (NoSuchMethodException ex2 ) {
201
- // no candidate destroy method found
202
- }
203
- }
204
- }
205
- return null ;
206
- }
207
- return (StringUtils .hasLength (destroyMethodName ) ? destroyMethodName : null );
208
- }
209
-
210
- /**
211
- * Search for all DestructionAwareBeanPostProcessors in the List.
212
- * @param processors the List to search
213
- * @return the filtered List of DestructionAwareBeanPostProcessors
214
- */
215
- @ Nullable
216
- private List <DestructionAwareBeanPostProcessor > filterPostProcessors (List <BeanPostProcessor > processors , Object bean ) {
217
- List <DestructionAwareBeanPostProcessor > filteredPostProcessors = null ;
218
- if (!CollectionUtils .isEmpty (processors )) {
219
- filteredPostProcessors = new ArrayList <>(processors .size ());
220
- for (BeanPostProcessor processor : processors ) {
221
- if (processor instanceof DestructionAwareBeanPostProcessor ) {
222
- DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor ) processor ;
223
- if (dabpp .requiresDestruction (bean )) {
224
- filteredPostProcessors .add (dabpp );
225
- }
226
- }
227
- }
228
- }
229
- return filteredPostProcessors ;
230
- }
231
-
232
-
233
174
@ Override
234
175
public void run () {
235
176
destroy ();
@@ -384,12 +325,50 @@ public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefin
384
325
if (bean instanceof DisposableBean || bean instanceof AutoCloseable ) {
385
326
return true ;
386
327
}
387
- String destroyMethodName = beanDefinition .getDestroyMethodName ();
388
- if (AbstractBeanDefinition .INFER_METHOD .equals (destroyMethodName )) {
389
- return (ClassUtils .hasMethod (bean .getClass (), CLOSE_METHOD_NAME ) ||
390
- ClassUtils .hasMethod (bean .getClass (), SHUTDOWN_METHOD_NAME ));
328
+ return inferDestroyMethodIfNecessary (bean , beanDefinition ) != null ;
329
+ }
330
+
331
+
332
+ /**
333
+ * If the current value of the given beanDefinition's "destroyMethodName" property is
334
+ * {@link AbstractBeanDefinition#INFER_METHOD}, then attempt to infer a destroy method.
335
+ * Candidate methods are currently limited to public, no-arg methods named "close" or
336
+ * "shutdown" (whether declared locally or inherited). The given BeanDefinition's
337
+ * "destroyMethodName" is updated to be null if no such method is found, otherwise set
338
+ * to the name of the inferred method. This constant serves as the default for the
339
+ * {@code @Bean#destroyMethod} attribute and the value of the constant may also be
340
+ * used in XML within the {@code <bean destroy-method="">} or {@code
341
+ * <beans default-destroy-method="">} attributes.
342
+ * <p>Also processes the {@link java.io.Closeable} and {@link java.lang.AutoCloseable}
343
+ * interfaces, reflectively calling the "close" method on implementing beans as well.
344
+ */
345
+ @ Nullable
346
+ private static String inferDestroyMethodIfNecessary (Object bean , RootBeanDefinition beanDefinition ) {
347
+ String destroyMethodName = beanDefinition .resolvedDestroyMethodName ;
348
+ if (destroyMethodName == null ) {
349
+ destroyMethodName = beanDefinition .getDestroyMethodName ();
350
+ if (AbstractBeanDefinition .INFER_METHOD .equals (destroyMethodName ) ||
351
+ (destroyMethodName == null && bean instanceof AutoCloseable )) {
352
+ // Only perform destroy method inference or Closeable detection
353
+ // in case of the bean not explicitly implementing DisposableBean
354
+ destroyMethodName = null ;
355
+ if (!(bean instanceof DisposableBean )) {
356
+ try {
357
+ destroyMethodName = bean .getClass ().getMethod (CLOSE_METHOD_NAME ).getName ();
358
+ }
359
+ catch (NoSuchMethodException ex ) {
360
+ try {
361
+ destroyMethodName = bean .getClass ().getMethod (SHUTDOWN_METHOD_NAME ).getName ();
362
+ }
363
+ catch (NoSuchMethodException ex2 ) {
364
+ // no candidate destroy method found
365
+ }
366
+ }
367
+ }
368
+ }
369
+ beanDefinition .resolvedDestroyMethodName = (destroyMethodName != null ? destroyMethodName : "" );
391
370
}
392
- return StringUtils .hasLength (destroyMethodName );
371
+ return ( StringUtils .hasLength (destroyMethodName ) ? destroyMethodName : null );
393
372
}
394
373
395
374
/**
@@ -411,4 +390,26 @@ public static boolean hasApplicableProcessors(Object bean, List<BeanPostProcesso
411
390
return false ;
412
391
}
413
392
393
+ /**
394
+ * Search for all DestructionAwareBeanPostProcessors in the List.
395
+ * @param processors the List to search
396
+ * @return the filtered List of DestructionAwareBeanPostProcessors
397
+ */
398
+ @ Nullable
399
+ private List <DestructionAwareBeanPostProcessor > filterPostProcessors (List <BeanPostProcessor > processors , Object bean ) {
400
+ List <DestructionAwareBeanPostProcessor > filteredPostProcessors = null ;
401
+ if (!CollectionUtils .isEmpty (processors )) {
402
+ filteredPostProcessors = new ArrayList <>(processors .size ());
403
+ for (BeanPostProcessor processor : processors ) {
404
+ if (processor instanceof DestructionAwareBeanPostProcessor ) {
405
+ DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor ) processor ;
406
+ if (dabpp .requiresDestruction (bean )) {
407
+ filteredPostProcessors .add (dabpp );
408
+ }
409
+ }
410
+ }
411
+ }
412
+ return filteredPostProcessors ;
413
+ }
414
+
414
415
}
0 commit comments