本文为原创,如需转载,请注明作者和出处,谢谢!
装配
Bean
是
Spring
的一个非常重要的功能。我们可以通过
Spring
在
XML
文件中配置
Java Bean
,然后通过
ApplicationContext
来获得
Bean
的对象实例。在配置
Bean
时,需要对构造方法的参数,属性进行初始化。对于
Java
简单类型或简单类型的
List
、
Map
等数据类型初始化非常简单,如下面就是一个对简单类型属性和构造方法参数进行初始化的配置代码:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
<!--
要求Spring2.0或Spring2.5scope="prototype"相当于Spring1.x的singleton="false"
-->
<
bean
id
="my"
class
="bean.MyClass"
scope
="prototype"
>
<
constructor-arg
>
<
value
>
myvalue1
</
value
>
</
constructor-arg
>
<
property
name
="name"
>
<
value
>
皮球
</
value
>
</
property
>
<
property
name
="myList"
>
<
list
>
<
value
>
value1
</
value
>
<
value
>
value2
</
value
>
</
list
>
</
property
>
</
bean
>
但对于复杂类型的属性或参数,如一个属性的类型是另外一个
Java Class
,这样就必须在配置文件中再声明这个
Java Class
,如果这种情况很多时,或是我们做的类要
release
时,就会给开发人员增加很多工作量。让我们先来举个例子。假设有两个类:
Contact
和
PhoneNumber
,
Contact
的
phoneNumber
属性的类型是
PhoneNumber
,代码如下:
Contact类
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
package
bean;
public
class
Contact
{
private
PhoneNumberphoneNumber;
public
PhoneNumbergetPhoneNumber()
{
return
phoneNumber;
}
public
void
setPhoneNumber(PhoneNumberphoneNumber)
{
this
.phoneNumber
=
phoneNumber;
}
}
PhoneNumber类
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
package
bean;
public
class
PhoneNumber
{
private
Stringnumber;
public
PhoneNumber(Strings)
{
this
.number
=
s;
}
public
StringgetNumber()
{
return
number;
}
}
如果直接在
XML
配置文件中装配
Contact
类,就需要先装配
PhoneNumber
类,代码如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
<?
xmlversion="1.0"encoding="UTF-8"
?>
<
beans
xmlns
="http://www.springframework.org/schema/beans"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx
="http://www.springframework.org/schema/tx"
xsi:schemaLocation
="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
>
<
bean
id
="contact"
class
="bean.Contact"
>
<
property
name
="phoneNumber"
>
<
ref
bean
="phoneNumber"
/>
</
property
>
</
bean
>
<
bean
id
="phoneNumber"
class
="bean.PhoneNumber"
>
<
constructor-arg
>
<
value
>
12345678
</
value
>
</
constructor-arg
>
</
bean
>
</
beans
>
从上面的代码中可以看到,装载Contact的同时,也装载了PhoneNumber。但如果使用了属性编辑器,就可以无需装载PhoneNumber就可以装载Contact了。
编写自己的属性编辑器的步骤很简单,属性编辑器类需要从
java.beans.PropertyEditorSupport
类继承,在这个类中有一个
setAsText
方法,这个方法有一个
String
类型的参数,通过这个方法,可以将
String
类型的参数值转换成其他类型的属性。在这个方法中我们还需要使用一个
setValue
方法,就来指定转换后的对象实例。好,现在我们来实现这个简单的编辑器类,代码如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
package
editor;
public
class
PhoneEditor
extends
java.beans.PropertyEditorSupport
{
@Override
public
void
setAsText(Stringtext)
throws
IllegalArgumentException
{
setValue(
new
bean.PhoneNumber(text));
}
}
这个类的代码非常简单,在
setAsText
方法中只有一行代码,实际上只是建立一个
PhoneNumber
对象实例,并将
text
属性值作为参数值传入
PhoneNumber
的构造方法。接下来我们在配置文件中安装这个属性编辑器(实际上是装配
org.springframework.beans.factory.config.CustomEditorConfigurer
类),代码如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
<
bean
id
="customerEditor"
class
="org.springframework.beans.factory.config.CustomEditorConfigurer"
>
<
property
name
="customEditors"
>
<
map
>
<
entry
key
="bean.PhoneNumber"
>
<
bean
id
="phoneEditor"
class
="editor.PhoneEditor"
/>
</
entry
>
</
map
>
</
property
>
</
bean
>
从上面的代码可以看出,属性编辑器是使用了
CustomEditorConfigurer
的
customEditors
属性进行安装的。这是一个
Map
类型的属性。
key
的值必须是属性编辑器最终转换后的类型名,如在本例中,要将文本的参数值转换成
bean.PhoneNumber
类型的值,因此,
key
必须为
bean.PhoneNumber
。
下面我们来使用
PhoneEditor
属性编辑器类来装配
Contact
类,代码如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
<
bean
id
="contact"
class
="bean.Contact"
>
<
property
name
="phoneNumber"
>
<
value
>
87654321
</
value
>
</
property
>
</
bean
>
也许大家都注意到了上面这段代码的变化,在设置phoneNumber属性默认值时,不再使用<ref>标签来引用phoneNumber对象,而是直接使用了<value>来设置一个文本的电话号。Spring当遇到这种情况时,也就是说,某个属性值和属性类型不一致时(如本例中一个是文本,一个是PhoneNumber类型),会先找一下属性类型是否有相应的属性编辑器已经被安装,在本例中将以bean.PhoneNumber作为key来查找,正好找到上面安装的PhoneEditor,因此,Spring就会调用PhoneEditor类中的setAsValue方法来设置PhoneNumber对象实例,然后Spring在内部又分调用getValue来获得PhoneNumber对象实例,并将其赋给Contact的phoneNumber属性。其实所有类型的bean.PhoneNumber的属性都可以使用这个属性编辑器。
大家可以看看,这样做是不是简单的多!尤其是在发布通用的framework或程序时,就更为简单了。在Spring中已经定义了很多这种属性编辑器,如我们可以使用org.springframework.beans.propertyeditors.URLEditor将字符串映射成java.net.URL对象。下面的代码通过ApplicationContext来获得Contact的对象实例,并输出其phoneNumber属性值:
import
org.springframework.context.
*
;
import
org.springframework.context.support.
*
;
public
class
Test
{
public
static
void
main(String[]args)
{
//
上面的配置代码都在applicationContext.xml文件中
ApplicationContextcontext
=
new
FileSystemXmlApplicationContext(
"
src\\applicationContext.xml
"
);
bean.Contactcontact
=
(bean.Contact)context.getBean(
"
contact
"
);
System.out.println(contact.getPhoneNumber().getNumber());
}
}
注:实际上,属性编辑器本身是由Java提供了,Spring只是利用了这一特性使装配一个Bean更容易而已。
国内最棒的Google Android技术社区(eoeandroid),欢迎访问!
《银河系列原创教程》发布
《Java Web开发速学宝典》出版,欢迎定购