27
27
import org .springframework .lang .Nullable ;
28
28
import org .springframework .util .ReflectionUtils ;
29
29
import org .springframework .util .StringUtils ;
30
+ import org .springframework .util .function .ThrowingSupplier ;
30
31
31
32
/**
32
33
* Simple object instantiation strategy for use in a BeanFactory.
@@ -59,7 +60,9 @@ public static Method getCurrentlyInvokedFactoryMethod() {
59
60
* the current value, if any.
60
61
* @param method the factory method currently being invoked or {@code null}
61
62
* @since 6.0
63
+ * @deprecated in favor of {@link #instantiateWithFactoryMethod(Method, ThrowingSupplier)}
62
64
*/
65
+ @ Deprecated (since = "6.2" , forRemoval = true )
63
66
public static void setCurrentlyInvokedFactoryMethod (@ Nullable Method method ) {
64
67
if (method != null ) {
65
68
currentlyInvokedFactoryMethod .set (method );
@@ -69,6 +72,31 @@ public static void setCurrentlyInvokedFactoryMethod(@Nullable Method method) {
69
72
}
70
73
}
71
74
75
+ /**
76
+ * Invoke the given {@code instanceSupplier} with the factory method exposed
77
+ * as being invoked.
78
+ * @param method the factory method to expose
79
+ * @param instanceSupplier the instance supplier
80
+ * @param <T> the type of the instance
81
+ * @return the result of the instance supplier
82
+ * @since 6.2
83
+ */
84
+ public static <T > T instantiateWithFactoryMethod (Method method , ThrowingSupplier <T > instanceSupplier ) {
85
+ Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod .get ();
86
+ try {
87
+ currentlyInvokedFactoryMethod .set (method );
88
+ return instanceSupplier .get ();
89
+ }
90
+ finally {
91
+ if (priorInvokedFactoryMethod != null ) {
92
+ currentlyInvokedFactoryMethod .set (priorInvokedFactoryMethod );
93
+ }
94
+ else {
95
+ currentlyInvokedFactoryMethod .remove ();
96
+ }
97
+ }
98
+ }
99
+
72
100
73
101
@ Override
74
102
public Object instantiate (RootBeanDefinition bd , @ Nullable String beanName , BeanFactory owner ) {
@@ -137,46 +165,40 @@ protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable
137
165
public Object instantiate (RootBeanDefinition bd , @ Nullable String beanName , BeanFactory owner ,
138
166
@ Nullable Object factoryBean , Method factoryMethod , Object ... args ) {
139
167
140
- try {
141
- ReflectionUtils .makeAccessible (factoryMethod );
142
-
143
- Method priorInvokedFactoryMethod = getCurrentlyInvokedFactoryMethod ();
168
+ return instantiateWithFactoryMethod (factoryMethod , () -> {
144
169
try {
145
- setCurrentlyInvokedFactoryMethod (factoryMethod );
170
+ ReflectionUtils . makeAccessible (factoryMethod );
146
171
Object result = factoryMethod .invoke (factoryBean , args );
147
172
if (result == null ) {
148
173
result = new NullBean ();
149
174
}
150
175
return result ;
151
176
}
152
- finally {
153
- setCurrentlyInvokedFactoryMethod (priorInvokedFactoryMethod );
177
+ catch (IllegalArgumentException ex ) {
178
+ if (factoryBean != null && !factoryMethod .getDeclaringClass ().isAssignableFrom (factoryBean .getClass ())) {
179
+ throw new BeanInstantiationException (factoryMethod ,
180
+ "Illegal factory instance for factory method '" + factoryMethod .getName () + "'; " +
181
+ "instance: " + factoryBean .getClass ().getName (), ex );
182
+ }
183
+ throw new BeanInstantiationException (factoryMethod ,
184
+ "Illegal arguments to factory method '" + factoryMethod .getName () + "'; " +
185
+ "args: " + StringUtils .arrayToCommaDelimitedString (args ), ex );
154
186
}
155
- }
156
- catch (IllegalArgumentException ex ) {
157
- if (factoryBean != null && !factoryMethod .getDeclaringClass ().isAssignableFrom (factoryBean .getClass ())) {
187
+ catch (IllegalAccessException ex ) {
158
188
throw new BeanInstantiationException (factoryMethod ,
159
- "Illegal factory instance for factory method '" + factoryMethod .getName () + "'; " +
160
- "instance: " + factoryBean .getClass ().getName (), ex );
189
+ "Cannot access factory method '" + factoryMethod .getName () + "'; is it public?" , ex );
161
190
}
162
- throw new BeanInstantiationException (factoryMethod ,
163
- "Illegal arguments to factory method '" + factoryMethod .getName () + "'; " +
164
- "args: " + StringUtils .arrayToCommaDelimitedString (args ), ex );
165
- }
166
- catch (IllegalAccessException ex ) {
167
- throw new BeanInstantiationException (factoryMethod ,
168
- "Cannot access factory method '" + factoryMethod .getName () + "'; is it public?" , ex );
169
- }
170
- catch (InvocationTargetException ex ) {
171
- String msg = "Factory method '" + factoryMethod .getName () + "' threw exception with message: " +
172
- ex .getTargetException ().getMessage ();
173
- if (bd .getFactoryBeanName () != null && owner instanceof ConfigurableBeanFactory cbf &&
174
- cbf .isCurrentlyInCreation (bd .getFactoryBeanName ())) {
175
- msg = "Circular reference involving containing bean '" + bd .getFactoryBeanName () + "' - consider " +
176
- "declaring the factory method as static for independence from its containing instance. " + msg ;
191
+ catch (InvocationTargetException ex ) {
192
+ String msg = "Factory method '" + factoryMethod .getName () + "' threw exception with message: " +
193
+ ex .getTargetException ().getMessage ();
194
+ if (bd .getFactoryBeanName () != null && owner instanceof ConfigurableBeanFactory cbf &&
195
+ cbf .isCurrentlyInCreation (bd .getFactoryBeanName ())) {
196
+ msg = "Circular reference involving containing bean '" + bd .getFactoryBeanName () + "' - consider " +
197
+ "declaring the factory method as static for independence from its containing instance. " + msg ;
198
+ }
199
+ throw new BeanInstantiationException (factoryMethod , msg , ex .getTargetException ());
177
200
}
178
- throw new BeanInstantiationException (factoryMethod , msg , ex .getTargetException ());
179
- }
201
+ });
180
202
}
181
203
182
204
}
0 commit comments