1
1
/*
2
- * Copyright 2002-2008 the original author or authors.
2
+ * Copyright 2002-2009 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.
@@ -58,9 +58,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
58
58
59
59
private final boolean invokeDisposableBean ;
60
60
61
- private final String destroyMethodName ;
61
+ private String destroyMethodName ;
62
62
63
- private final boolean enforceDestroyMethod ;
63
+ private transient Method destroyMethod ;
64
64
65
65
private List <DestructionAwareBeanPostProcessor > beanPostProcessors ;
66
66
@@ -79,35 +79,55 @@ public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition be
79
79
Assert .notNull (bean , "Bean must not be null" );
80
80
this .bean = bean ;
81
81
this .beanName = beanName ;
82
- this .invokeDisposableBean = !beanDefinition .isExternallyManagedDestroyMethod ("destroy" );
83
- this .destroyMethodName =
84
- (!beanDefinition .isExternallyManagedDestroyMethod (beanDefinition .getDestroyMethodName ()) ?
85
- beanDefinition .getDestroyMethodName () : null );
86
- this .enforceDestroyMethod = beanDefinition .isEnforceDestroyMethod ();
82
+ this .invokeDisposableBean =
83
+ (this .bean instanceof DisposableBean && !beanDefinition .isExternallyManagedDestroyMethod ("destroy" ));
84
+ String destroyMethodName = beanDefinition .getDestroyMethodName ();
85
+ if (destroyMethodName != null && !(this .invokeDisposableBean && "destroy" .equals (destroyMethodName )) &&
86
+ !beanDefinition .isExternallyManagedDestroyMethod (destroyMethodName )) {
87
+ this .destroyMethodName = destroyMethodName ;
88
+ try {
89
+ this .destroyMethod = BeanUtils .findMethodWithMinimalParameters (bean .getClass (), destroyMethodName );
90
+ }
91
+ catch (IllegalArgumentException ex ) {
92
+ throw new BeanDefinitionValidationException ("Couldn't find a unique destroy method on bean with name '" +
93
+ this .beanName + ": " + ex .getMessage ());
94
+ }
95
+ if (this .destroyMethod == null ) {
96
+ if (beanDefinition .isEnforceDestroyMethod ()) {
97
+ throw new BeanDefinitionValidationException ("Couldn't find a destroy method named '" +
98
+ destroyMethodName + "' on bean with name '" + beanName + "'" );
99
+ }
100
+ }
101
+ else {
102
+ Class [] paramTypes = this .destroyMethod .getParameterTypes ();
103
+ if (paramTypes .length > 1 ) {
104
+ throw new BeanDefinitionValidationException ("Method '" + destroyMethodName + "' of bean '" +
105
+ beanName + "' has more than one parameter - not supported as destroy method" );
106
+ }
107
+ else if (paramTypes .length == 1 && !paramTypes [0 ].equals (boolean .class )) {
108
+ throw new BeanDefinitionValidationException ("Method '" + destroyMethodName + "' of bean '" +
109
+ beanName + "' has a non-boolean parameter - not supported as destroy method" );
110
+ }
111
+ }
112
+ }
87
113
this .beanPostProcessors = filterPostProcessors (postProcessors );
88
114
}
89
115
90
116
/**
91
117
* Create a new DisposableBeanAdapter for the given bean.
92
118
* @param bean the bean instance (never <code>null</code>)
93
119
* @param beanName the name of the bean
94
- * @param invokeDisposableBean whether to actually invoke
95
- * DisposableBean's destroy method here
96
- * @param destroyMethodName the name of the custom destroy method
97
- * (<code>null</code> if there is none)
98
- * @param enforceDestroyMethod whether to the specified custom
99
- * destroy method (if any) has to be present on the bean object
120
+ * @param invokeDisposableBean whether to actually invoke DisposableBean's destroy method here
121
+ * @param destroyMethodName the name of the custom destroy method (<code>null</code> if there is none)
100
122
* @param postProcessors the List of DestructionAwareBeanPostProcessors, if any
101
123
*/
102
124
private DisposableBeanAdapter (Object bean , String beanName , boolean invokeDisposableBean ,
103
- String destroyMethodName , boolean enforceDestroyMethod ,
104
- List <DestructionAwareBeanPostProcessor > postProcessors ) {
125
+ String destroyMethodName , List <DestructionAwareBeanPostProcessor > postProcessors ) {
105
126
106
127
this .bean = bean ;
107
128
this .beanName = beanName ;
108
129
this .invokeDisposableBean = invokeDisposableBean ;
109
130
this .destroyMethodName = destroyMethodName ;
110
- this .enforceDestroyMethod = enforceDestroyMethod ;
111
131
this .beanPostProcessors = postProcessors ;
112
132
}
113
133
@@ -142,8 +162,7 @@ public void destroy() {
142
162
}
143
163
}
144
164
145
- boolean isDisposableBean = (this .bean instanceof DisposableBean );
146
- if (isDisposableBean && this .invokeDisposableBean ) {
165
+ if (this .invokeDisposableBean ) {
147
166
if (logger .isDebugEnabled ()) {
148
167
logger .debug ("Invoking destroy() on bean with name '" + this .beanName + "'" );
149
168
}
@@ -161,8 +180,13 @@ public void destroy() {
161
180
}
162
181
}
163
182
164
- if (this .destroyMethodName != null && !(isDisposableBean && "destroy" .equals (this .destroyMethodName ))) {
165
- invokeCustomDestroyMethod ();
183
+ if (this .destroyMethod != null ) {
184
+ invokeCustomDestroyMethod (this .destroyMethod );
185
+ }
186
+ else if (this .destroyMethodName != null ) {
187
+ Method destroyMethod =
188
+ BeanUtils .findMethodWithMinimalParameters (this .bean .getClass (), this .destroyMethodName );
189
+ invokeCustomDestroyMethod (destroyMethod );
166
190
}
167
191
}
168
192
@@ -172,62 +196,33 @@ public void destroy() {
172
196
* for a method with a single boolean argument (passing in "true",
173
197
* assuming a "force" parameter), else logging an error.
174
198
*/
175
- private void invokeCustomDestroyMethod () {
199
+ private void invokeCustomDestroyMethod (Method destroyMethod ) {
200
+ Class [] paramTypes = destroyMethod .getParameterTypes ();
201
+ Object [] args = new Object [paramTypes .length ];
202
+ if (paramTypes .length == 1 ) {
203
+ args [0 ] = Boolean .TRUE ;
204
+ }
205
+ if (logger .isDebugEnabled ()) {
206
+ logger .debug ("Invoking destroy method '" + this .destroyMethodName +
207
+ "' on bean with name '" + this .beanName + "'" );
208
+ }
209
+ ReflectionUtils .makeAccessible (destroyMethod );
176
210
try {
177
- Method destroyMethod =
178
- BeanUtils . findMethodWithMinimalParameters ( this . bean . getClass (), this . destroyMethodName );
179
- if ( destroyMethod == null ) {
180
- if ( this .enforceDestroyMethod ) {
181
- logger . warn ( "Couldn't find a destroy method named '" + this .destroyMethodName +
182
- "' on bean with name '" + this . beanName + "'" );
183
- }
211
+ destroyMethod . invoke ( this . bean , args );
212
+ }
213
+ catch ( InvocationTargetException ex ) {
214
+ String msg = "Invocation of destroy method '" + this .destroyMethodName +
215
+ "' failed on bean with name '" + this .beanName + "'" ;
216
+ if ( logger . isDebugEnabled ()) {
217
+ logger . warn ( msg , ex . getTargetException ());
184
218
}
185
-
186
219
else {
187
- Class [] paramTypes = destroyMethod .getParameterTypes ();
188
- if (paramTypes .length > 1 ) {
189
- logger .error ("Method '" + this .destroyMethodName + "' of bean '" + this .beanName +
190
- "' has more than one parameter - not supported as destroy method" );
191
- }
192
- else if (paramTypes .length == 1 && !paramTypes [0 ].equals (boolean .class )) {
193
- logger .error ("Method '" + this .destroyMethodName + "' of bean '" + this .beanName +
194
- "' has a non-boolean parameter - not supported as destroy method" );
195
- }
196
-
197
- else {
198
- Object [] args = new Object [paramTypes .length ];
199
- if (paramTypes .length == 1 ) {
200
- args [0 ] = Boolean .TRUE ;
201
- }
202
- if (logger .isDebugEnabled ()) {
203
- logger .debug ("Invoking destroy method '" + this .destroyMethodName +
204
- "' on bean with name '" + this .beanName + "'" );
205
- }
206
- ReflectionUtils .makeAccessible (destroyMethod );
207
- try {
208
- destroyMethod .invoke (this .bean , args );
209
- }
210
- catch (InvocationTargetException ex ) {
211
- String msg = "Invocation of destroy method '" + this .destroyMethodName +
212
- "' failed on bean with name '" + this .beanName + "'" ;
213
- if (logger .isDebugEnabled ()) {
214
- logger .warn (msg , ex .getTargetException ());
215
- }
216
- else {
217
- logger .warn (msg + ": " + ex .getTargetException ());
218
- }
219
- }
220
- catch (Throwable ex ) {
221
- logger .error ("Couldn't invoke destroy method '" + this .destroyMethodName +
222
- "' on bean with name '" + this .beanName + "'" , ex );
223
- }
224
- }
220
+ logger .warn (msg + ": " + ex .getTargetException ());
225
221
}
226
222
}
227
- catch (IllegalArgumentException ex ) {
228
- // thrown from findMethodWithMinimalParameters
229
- logger .error ("Couldn't find a unique destroy method on bean with name '" +
230
- this .beanName + ": " + ex .getMessage ());
223
+ catch (Throwable ex ) {
224
+ logger .error ("Couldn't invoke destroy method '" + this .destroyMethodName +
225
+ "' on bean with name '" + this .beanName + "'" , ex );
231
226
}
232
227
}
233
228
@@ -247,7 +242,7 @@ protected Object writeReplace() {
247
242
}
248
243
}
249
244
return new DisposableBeanAdapter (this .bean , this .beanName , this .invokeDisposableBean ,
250
- this .destroyMethodName , this . enforceDestroyMethod , serializablePostProcessors );
245
+ this .destroyMethodName , serializablePostProcessors );
251
246
}
252
247
253
248
}
0 commit comments