7.10.3 获取方法返回值

7.10.3 获取方法返回值

通过MethodInvokingFactoryBean这个工厂Bean,可调用任意类的类方法,也可调用任意对象的实例方法,如果调用的方法有返回值,则既可将该指定方法的返回值定义成容器中的Bean,也可将指定方法的返回值注入给其他Bean
使用MethodInvokingFactoryBean来调用任意方法时,可分为两种情形。

调用静态方法

如果希望调用的方法是静态方法,则需要指定:

  1. 调用哪个类。通过MethodInvokingFactoryBeansetTargetClass(String targetClass)方法指定。
  2. 调用哪个方法。通过MethodInvokingFactoryBeansetMethod(String targetMethod)方法指定。
  3. 调用方法的参数。通过MethodInvokingFactoryBeansetArguments(Object[] arguments)方法指定。如果希望调用的方法无须参数,则可以省略该配置。

调用实例方法

如果希望调用的方法是实例方法,则需要指定:

  1. 调用哪个对象。通过MethodInvokingFactoryBeansetTargetobject(Object targetObject)方法指定。
  2. 调用哪个方法。通过MethodInvokingFactoryBeansetTargetMethod(String targetMethod)方法指定。
  3. 调用方法的参数。通过MethodInvokingFactoryBeansetArguments(Object[] arguments)方法指定。如果希望调用的方法无须参数,则可以省略该配置。

假设有如下一段Java代码:

1
2
3
4
5
6
7
8
9
10
11
JFrame win=new JFrame("我的窗口");
JTextArea jta=JTextArea(7,40);
win.add(new JScrollPane(jta));
JPanel jp=new JPanel();
win.add(jp,BorderLayout.SOUTH)
JButton jb1=new JButton("确定");
jp.add(jb1);
JButton jp2=new JButton("取消");
jp.add(jb2);
win.pack();
win.setVisible(true);

这段代码是一段很”随意”的Java代码(可以是任意一段Java代码),别人给你任何一段Java代码,你都应该能用Spring配置文件将它配置出来。

程序示例

1
2
3
4
5
E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\MethodInvokingFactoryBean
└─src\
├─beans.xml
└─lee\
└─SpringTest.java

下面使用XML配置文件将上面这段Java代码配置出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 下面配置相当于如下Java代码:
JFrame win = new JFrame("我的窗口");
win.setVisible(true); -->
<bean id="win" class="javax.swing.JFrame">
<constructor-arg value="我的窗口" type="java.lang.String"/>
<property name="visible" value="true"/>
</bean>

<!-- 下面配置相当于如下Java代码:
JTextArea jta = JTextArea(7, 40); -->
<bean id="jta" class="javax.swing.JTextArea">
<constructor-arg value="7" type="int"/>
<constructor-arg value="40" type="int"/>
</bean>

<!-- 使用MethodInvokingFactoryBean驱动Spring调用普通方法
下面配置相当于如下Java代码:
win.add(new JScrollPane(jta)); -->
<bean class=
"org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="win"/>
<property name="targetMethod" value="add"/>
<property name="arguments">
<list>
<bean class="javax.swing.JScrollPane">
<constructor-arg ref="jta"/>
</bean>
</list>
</property>
</bean>

<!-- 下面配置相当于如下Java代码:
JPanel jp = new JPanel(); -->
<bean id="jp" class="javax.swing.JPanel"/>

<!-- 使用MethodInvokingFactoryBean驱动Spring调用普通方法
下面配置相当于如下Java代码:
win.add(jp , BorderLayout.SOUTH); -->
<bean class=
"org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="win"/>
<property name="targetMethod" value="add"/>
<property name="arguments">
<list>
<ref bean="jp"/>
<util:constant static-field="java.awt.BorderLayout.SOUTH"/>
</list>
</property>
</bean>

<!-- 下面配置相当于如下Java代码:
JButton jb1 = new JButton("确定"); -->
<bean id="jb1" class="javax.swing.JButton">
<constructor-arg value="确定" type="java.lang.String"/>
</bean>

<!-- 使用MethodInvokingFactoryBean驱动Spring调用普通方法
下面配置相当于如下Java代码:
jp.add(jb1); -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jp"/>
<property name="targetMethod" value="add"/>
<property name="arguments">
<list>
<ref bean="jb1"/>
</list>
</property>
</bean>

<!-- 下面配置相当于如下Java代码:
JButton jb2 = new JButton("取消"); -->
<bean id="jb2" class="javax.swing.JButton">
<constructor-arg value="取消" type="java.lang.String"/>
</bean>

<!-- 使用MethodInvokingFactoryBean驱动Spring调用普通方法
下面配置相当于如下Java代码:
jp.add(jb2); -->
<bean class=
"org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="jp"/>
<property name="targetMethod" value="add"/>
<property name="arguments">
<list>
<ref bean="jb2"/>
</list>
</property>
</bean>
<!-- 使用MethodInvokingFactoryBean驱动Spring调用普通方法
下面配置相当于如下Java代码:
win.pack(); -->
<bean class=
"org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="win"/>
<property name="targetMethod" value="pack"/>
</bean>
</beans>

该示例的主程序非常简单,主程序只是简单的行:用于创建Spring容器。编译、运行该程序,可以看到如图7.4所示的界面。
通过上面示例证实了一点:几乎所有的Java代码都可以通过Spring XML配置文件配置出来连上面的Swing编程都可使用Spring XML配置文件来驱动。需要说明的是,此处只是向读者示范如何使用Spring配置文件来驱动执行任意一段Java代码,并非要大家使用Spring XML配置文件进行Swing界面编程.
经过上面的介绍不难发现: Spring框架的本质其实就是通过XML配置来执行Java代码,因此几乎可以把所有的Java代码放到Spring配置文件中管理。归纳一下:

  1. 调用构造器创建对象(包括使用工厂方法创建对象),用<bean>元素。
  2. 调用setter方法,用<property>元素。
  3. 调用getter方法,用PropertyPathFactoryBean<util:property-path>元素。
  4. 获取Field的值,用FieldRetrievingFactoryBean<util:constant>元素。
  5. 调用普通方法,用MethodInvokingFactoryBean工厂Bean

那么是否有必要把所有的Java代码都放在Sprin配置文件中管理呢?答案是否定的。过度使用XML配置文件不仅使得配置文件更加臃肿,难以维护,而且导致程序的可读性严重降低。
一般来说,应该将如下两类信息放到XML配置文件中管理。

  1. 项目升级、维护时经常需要改动的信息
  2. 控制项目内各组件耦合关系的代码。

这样就体现了Spring IoC容器的作用:将原来使用Java代码管理的耦合关系,提取到XML中进行管理,从而降低了各组件之间的耦合,提高了软件系统的可维护性