11/*
2- * Copyright 2002-2012 the original author or authors.
2+ * Copyright 2002-2014 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1616
1717package org .springframework .beans .factory .config ;
1818
19- import java .lang .reflect .InvocationTargetException ;
20-
21- import org .springframework .beans .TypeConverter ;
22- import org .springframework .beans .factory .BeanClassLoaderAware ;
23- import org .springframework .beans .factory .BeanFactory ;
24- import org .springframework .beans .factory .BeanFactoryAware ;
2519import org .springframework .beans .factory .FactoryBean ;
2620import org .springframework .beans .factory .FactoryBeanNotInitializedException ;
27- import org .springframework .beans .factory .InitializingBean ;
28- import org .springframework .beans .support .ArgumentConvertingMethodInvoker ;
29- import org .springframework .util .ClassUtils ;
3021
3122/**
3223 * {@link FactoryBean} which returns a value which is the result of a static or instance
4435 * {@link #setSingleton singleton} property may be set to "false", to cause this
4536 * factory to invoke the target method each time it is asked for an object.
4637 *
47- * <p>A static target method may be specified by setting the
48- * {@link #setTargetMethod targetMethod} property to a String representing the static
49- * method name, with {@link #setTargetClass targetClass} specifying the Class that
50- * the static method is defined on. Alternatively, a target instance method may be
38+ * <p><b>NOTE: If your target method does not produce a result to expose, consider
39+ * {@link MethodInvokingBean} instead, which avoids the type determination and
40+ * lifecycle limitations that this {@link MethodInvokingFactoryBean} comes with.</b>
41+ *
42+ * <p>This invoker supports any kind of target method. A static method may be specified
43+ * by setting the {@link #setTargetMethod targetMethod} property to a String representing
44+ * the static method name, with {@link #setTargetClass targetClass} specifying the Class
45+ * that the static method is defined on. Alternatively, a target instance method may be
5146 * specified, by setting the {@link #setTargetObject targetObject} property as the target
5247 * object, and the {@link #setTargetMethod targetMethod} property as the name of the
5348 * method to call on that target object. Arguments for the method invocation may be
6156 *
6257 * <pre class="code">
6358 * <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
64- * <property name="staticMethod">< value> com.whatever.MyClassFactory.getInstance</value></property >
59+ * <property name="staticMethod" value=" com.whatever.MyClassFactory.getInstance"/ >
6560 * </bean></pre>
6661 *
6762 * <p>An example of calling a static method then an instance method to get at a
6863 * Java system property. Somewhat verbose, but it works.
6964 *
7065 * <pre class="code">
7166 * <bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
72- * <property name="targetClass">< value> java.lang.System</value></property >
73- * <property name="targetMethod">< value> getProperties</value></property >
67+ * <property name="targetClass" value=" java.lang.System"/ >
68+ * <property name="targetMethod" value=" getProperties"/ >
7469 * </bean>
7570 *
7671 * <bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
77- * <property name="targetObject"><ref local="sysProps"/></property>
78- * <property name="targetMethod"><value>getProperty</value></property>
79- * <property name="arguments">
80- * <list>
81- * <value>java.version</value>
82- * </list>
83- * </property>
72+ * <property name="targetObject" value="sysProps"/>
73+ * <property name="targetMethod" value="getProperty"/>
74+ * <property name="arguments" value="java.version"/>
8475 * </bean></pre>
8576 *
8677 * @author Colin Sampaleanu
8778 * @author Juergen Hoeller
8879 * @since 21.11.2003
80+ * @see MethodInvokingBean
81+ * @see org.springframework.util.MethodInvoker
8982 */
90- public class MethodInvokingFactoryBean extends ArgumentConvertingMethodInvoker
91- implements FactoryBean <Object >, BeanClassLoaderAware , BeanFactoryAware , InitializingBean {
83+ public class MethodInvokingFactoryBean extends MethodInvokingBean implements FactoryBean <Object > {
9284
9385 private boolean singleton = true ;
9486
95- private ClassLoader beanClassLoader = ClassUtils .getDefaultClassLoader ();
96-
97- private ConfigurableBeanFactory beanFactory ;
98-
9987 private boolean initialized = false ;
10088
10189 /** Method call result in the singleton case */
@@ -104,75 +92,18 @@ public class MethodInvokingFactoryBean extends ArgumentConvertingMethodInvoker
10492
10593 /**
10694 * Set if a singleton should be created, or a new object on each
107- * request else . Default is "true".
95+ * {@link #getObject()} request otherwise . Default is "true".
10896 */
10997 public void setSingleton (boolean singleton ) {
11098 this .singleton = singleton ;
11199 }
112100
113- @ Override
114- public boolean isSingleton () {
115- return this .singleton ;
116- }
117-
118- @ Override
119- public void setBeanClassLoader (ClassLoader classLoader ) {
120- this .beanClassLoader = classLoader ;
121- }
122-
123- @ Override
124- protected Class <?> resolveClassName (String className ) throws ClassNotFoundException {
125- return ClassUtils .forName (className , this .beanClassLoader );
126- }
127-
128- @ Override
129- public void setBeanFactory (BeanFactory beanFactory ) {
130- if (beanFactory instanceof ConfigurableBeanFactory ) {
131- this .beanFactory = (ConfigurableBeanFactory ) beanFactory ;
132- }
133- }
134-
135- /**
136- * Obtain the TypeConverter from the BeanFactory that this bean runs in,
137- * if possible.
138- * @see ConfigurableBeanFactory#getTypeConverter()
139- */
140- @ Override
141- protected TypeConverter getDefaultTypeConverter () {
142- if (this .beanFactory != null ) {
143- return this .beanFactory .getTypeConverter ();
144- }
145- else {
146- return super .getDefaultTypeConverter ();
147- }
148- }
149-
150-
151101 @ Override
152102 public void afterPropertiesSet () throws Exception {
153103 prepare ();
154104 if (this .singleton ) {
155105 this .initialized = true ;
156- this .singletonObject = doInvoke ();
157- }
158- }
159-
160- /**
161- * Perform the invocation and convert InvocationTargetException
162- * into the underlying target exception.
163- */
164- private Object doInvoke () throws Exception {
165- try {
166- return invoke ();
167- }
168- catch (InvocationTargetException ex ) {
169- if (ex .getTargetException () instanceof Exception ) {
170- throw (Exception ) ex .getTargetException ();
171- }
172- if (ex .getTargetException () instanceof Error ) {
173- throw (Error ) ex .getTargetException ();
174- }
175- throw ex ;
106+ this .singletonObject = invokeWithTargetException ();
176107 }
177108 }
178109
@@ -193,7 +124,7 @@ public Object getObject() throws Exception {
193124 }
194125 else {
195126 // Prototype: new object on each call.
196- return doInvoke ();
127+ return invokeWithTargetException ();
197128 }
198129 }
199130
@@ -210,4 +141,9 @@ public Class<?> getObjectType() {
210141 return getPreparedMethod ().getReturnType ();
211142 }
212143
144+ @ Override
145+ public boolean isSingleton () {
146+ return this .singleton ;
147+ }
148+
213149}
0 commit comments