Spring-IOC MethodInvokingFactoryBean 类源码解析

MethodInvokingFactoryBean

MethodInvokingFactoryBean的作用是,通过定义类和它的方法,然后生成的bean是这个方法的返回值,即可以注入方法返回值。

MethodInvokingFactoryBean用来获得某个方法的返回值,该方法既可以是静态方法,也可以是实例方法。

该方法的返回值可以注入bean实例属性,也可以直接定义成bean实例。

静态方法返回值注入

配置:

方式1:直接注入staticMethod属性,写明类的全限定名加方法名:

 <bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
     <property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/>
 </bean>

Spring会将此属性切分为class和method,就和方式2的配置结果一样。具体源码如下:

public void prepare() throws ClassNotFoundException, NoSuchMethodException {
                // 此属性不为空,进行拆分
		if (this.staticMethod != null) {
			int lastDotIndex = this.staticMethod.lastIndexOf('.');
			if (lastDotIndex == -1 || lastDotIndex == this.staticMethod.length()) {
				throw new IllegalArgumentException(
						"staticMethod must be a fully qualified class plus method name: " +
						"e.g. 'example.MyExampleClass.myExampleMethod'");
			}
			String className = this.staticMethod.substring(0, lastDotIndex);
			String methodName = this.staticMethod.substring(lastDotIndex + 1);
			this.targetClass = resolveClassName(className);
			this.targetMethod = methodName;
		}

		Class<?> targetClass = getTargetClass();
		String targetMethod = getTargetMethod();
		Assert.notNull(targetClass, "Either 'targetClass' or 'targetObject' is required");
		Assert.notNull(targetMethod, "Property 'targetMethod' is required");

		Object[] arguments = getArguments();
		Class<?>[] argTypes = new Class<?>[arguments.length];
		for (int i = 0; i < arguments.length; ++i) {
			argTypes[i] = (arguments[i] != null ? arguments[i].getClass() : Object.class);
		}

		// Try to get the exact method first.
		try {
			this.methodObject = targetClass.getMethod(targetMethod, argTypes);
		}
		catch (NoSuchMethodException ex) {
			// Just rethrow exception if we can't get any match.
			this.methodObject = findMatchingMethod();
			if (this.methodObject == null) {
				throw ex;
			}
		}
	}

方式二

<bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
         <property name="targetClass" value="java.lang.System"/>
         <property name="targetMethod" value="getProperties"/>
 </bean>

增加参数

<bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
     <property name="targetObject" ref="sysProps"/>
     <property name="targetMethod" value="getProperty"/>
     <property name="arguments" value="java.version"/>
 </bean>

应用 -- 初始化Spring容器时,将某些配置注入到环境变量中

<bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
         <property name="targetClass" value="java.lang.System"/>
         <property name="targetMethod" value="getProperties"/>
 </bean>


<bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
     <property name="targetObject" ref="sysProps"/>
     <property name="targetMethod" value="putAll"/>
     <property name="arguments">
          <props>
                     <prop key="kafka.consumer.host">10.10.10.48:9092</prop>
         </props>
      </property>
 </bean>

如上就将kafka.consumer.host注入到了环境变量中

posted @ 2018-04-13 00:55  枫叶maple  阅读(612)  评论(0编辑  收藏  举报