7.10.2 获取Field值

7.10.2 获取Field值

通过FieldRetrievingFactoryBean类,可访问类的静态Field值或对象的实例FieldFieldRetrieving Factory Bean获得指定Field的值之后,即可将获取的值注入其他Bean,也可直接定义成新的Bean
使用FieldRetrievingFactoryBean访问Field值可分为两种情形:
如果要访问的Field是静态Field,则需要指定:

  1. 调用哪个类。由FieldRetrievingFactoryBeansetTarget Class( String targetClass方法指定。
  2. 访问哪个Field。由FieldRetrievingFactoryBeansetTargetField(String target Field)方法指定。

如果要访问的Field是实例Field,则需要指定:

  1. 调用哪个对象。由FieldRetrievingFactoryBeansetTargetObject(Object targetObject)方法指定。
  2. 访问哪个Field。由FieldRetrievingFactoryBeansetTargetField(String targetField)方法指定

常用的是访问静态的Field

对于FieldRetrievingFactoryBean的第一种用法,与前面介绍FactoryBean时自己开发的GetFieldFactoryBean基本相同。对于FieldRetrievingFactoryBean的第二种用法,在实际编程中几乎没多大用处,这是因为FieldRetrievingFactoryBean则要求实例的Field要以public修饰,但是根据良好封装原则,Java类的实例Field应该用private修饰,并使用gettersetter来访问和修改,这与FieldRetrievingFactoryBean的要求矛盾。

程序示例

项目结构

1
2
3
4
5
6
7
8
9
10
11
E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\FieldRetrievingFactoryBean
└─src\
├─beans.xml
├─lee\
│ └─SpringTest.java
└─org\
└─crazyit\
└─app\
└─service\
├─Person.java
└─Son.java

下面配置用于将指定类的静态Field定义成容器中的Bean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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">

<!-- 将指定类的静态Field值定义成容器中的Bean实例-->
<bean id="theAge1" class=
"org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<!-- targetClass指定访问哪个目标类 -->
<property name="targetClass" value="java.sql.Connection"/>
<!-- targetField指定要访问的Field名 -->
<property name="targetField" value="TRANSACTION_SERIALIZABLE"/>
</bean>
</beans>

上面的XML配置粗体字代码指定访问java.sql.ConnectionTRANSACTION_SERIALIZABLE的值,并将该Fied的值定义成容器中的the Agel bean查阅JDK API文档即可发现该Field的值为8因此theAgel的值就是8。
主程序部分访问theAge1的代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package lee;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest
{
public static void main(String[] args)
{
@SuppressWarnings("resource")
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"beans.xml");
System.out.println("系统获取theAge1的值:" + ctx.getBean("theAge1"));
}
}

编译、运行该程序,将可看到如下输出:

1
系统获取theAge1的值:8

FieldRetrievingFactoryBean还提供了一个setStaticField(String staticField)方法,该方法可同时指定获取哪个类的哪个静态Field值。因此上面的配置片段可简化为如下形式:

1
2
3
4
5
6
<bean id="theAge2"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<!-- staticField指定访问哪个类的哪个静态Field -->
<property name="staticField"
value="java.sql.Connection.TRANSACTION_SERIALIZABLE" />
</bean>

使用FieldRetrievingFactory Bean获取的Field值既可定义成容器中的Bean,也可被注入到其他Bean中。例如如下配置。

1
2
3
4
5
6
7
<bean id="son" class="org.crazyit.app.service.Son">
<property name="age">
<!-- 指定java.sql.Connection.TRANSACTION_SERIALIZABLE 作为调用setAge()方法的参数值 -->
<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />
</property>
</bean>

主程序使用如下代码来访问、输出容器中的son:

1
System.out.println("系统获取son为:" + ctx.getBean("son"));

程序的执行结果如下:

1
系统获取son为:Son[age= 8]

从程序输出可以看出,sonage成员变量的值,等于java.sql.Connection接口中TRANSACTIONSERIALIZABLE的值。在上面定义中,定义FieldRetrievingFactoryBean工厂Bean时指定的id属性,并不是该工厂Bean实例的唯一标识,而是用来指定Field的表达式

util:constant元素

util:命名空间下的<util:constant>元素可作为FieldRetrievingFactoryBean访问静态Field的简化配置,使用该元素时可指定如下两个属性。

属性 描述
id 该属性指定将静态Field的值定义成名为idBean实例。
static-field 该属性指定访问哪个类的哪个静态Field

上面的theAge1theAge2可简化为如下配置:

1
2
<util:constant id="theAge1"
static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE" />

上面的son Bean可简化为如下配置:

1
2
3
4
5
6
<bean id="son" class="org.crazyit.app.service.Son">
<property name="age">
<util:constant
static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE" />
</property>
</bean>