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