在Spring刚刚出现的时候,Xml是描述配置的主要方式。但现在的Spring有了强大的自动化配置和基于Java的配置。Xml不再是第一选择,不过鉴于那么多基于Xml的Spring配置,如何理解Spring的Xml配置还是非常重要的。下面详细的说一下Spring中的Xml配置。
首先需要在Xml中创建Spring的配置规范。最为简单的Xml配置如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
</beans>
在配置文件的顶部申明多个Xml模式(XSD)文件。这些文件定义了配置Spring的xml元素。创建和管理Spring文件的一种便捷方式是使用Spring ToolSuite。在Eclipse中安装Spring Tool Suite方法。
在讲在Xml配置bean前先创建一个例子。
cd类
package com.zwq.XmlZhuangpei;
import org.springframework.stereotype.Component;
public class ZjlPeppers implements CompactDisc{
private String title="周杰伦的歌";
private String artist="Cd碟";
@Override
public void play() {
System.out.println("Playing:"+title+" By"+artist);
}
}
cd播放器
package com.zwq.XmlZhuangpei;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
public class CdPlayer implements MediaPlayer{
private CompactDisc cd;
public CdPlayer(CompactDisc cd){
this.cd=cd;
}
public void play(){
cd.play();
}
}
Cd播放器依赖于Cd类
在Xml配置中申明cd类的bean和Cd播放器的bean。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="cd" class="com.zwq.XmlZhuangpei.ZjlPeppers"></bean>
<bean id="CdPlayer" class="com.zwq.XmlZhuangpei.CdPlayer">
<constructor-arg ref="cd"/>
</bean>
</beans>
在上面的Xml配置代码中我们先配置了ZjlPeppers类的bean。在申明这个bean的时候我们使用了Spring-bean模式中的bean元素。并通过这个元素的class属性指定创建这个bean的类,并需要使用权限定的类名。其中的id属性指明了bean的名称。如果不写id属性那么他的id就是“com.zwq.XmlZhuangpei.ZjlPeppers#0”,#0是一个计数形式用来区分其他同类型的bean。如果另外声明了一个ZjlPeppers,并没有进行标识,那么他的id就是“com.zwq.XmlZhuangpei.ZjlPeppers#1”.在Spring发现这个bean元素时,会调用他的默认构造器来创建这个bean。
在第二个bean元素中借用构造器注入bean。当Spring遇到这个bean元素的时候他会创建一个CdPlayer实例。constructor-arg元素会告诉Spring将一个id为cd的bean引用传入CdPlayer的构造器中。
在XMl配置构造器注入时Spring提供了两种方式
- 使用constructor-arg元素进行构造器注入
- 使用Spring3.0所引入的c-命名空间进行构造器注入
**使用constructor-arg元素进行构造器注入时需要将他的ref属性指向你需要注入的bean的id。而在c-命名空间进行构造器注入时必须要在他的顶部申明其模式。**代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
</beans>
在c-命名空间和模式申明之后,就可以使用它来申明构造器参数了。如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="cdZjl" class="com.zwq.XmlZhuangpei.ZjlPeppers"></bean>
<bean id="CdPlayer" class="com.zwq.XmlZhuangpei.CdPlayer" c:cd-ref="cdZjl"/>
</beans>
在第二个bean中使用了c-命名空间进行构造器注入。他作为bean元素的一个属性,属性名“c:”接下来是要装配的构造器参数名“cd”,在此之后是“-ref”这是一个命名约定,他告诉Spring正在装配的是一个bean的引用,这个bean的名字是cdZjl。这里直接引用了构造器参数名,但这种形式是不大方便的,当我们进行代码优化的时候可能会修改参数名称。这是有另外一种使用的方式如下
<bean id="CdPlayer" class="com.zwq.XmlZhuangpei.CdPlayer" c:_0-ref="cdZjl"/>
这里的0表示的是参数索引。因为Xml不容许数字作为属性的第一个字符所以变为下划线加索引的形式_0。
1).构造器注入之字面量注入
有时候在开发中不全是类型注入,还有字面量注入如下这个类:
package com.zwq.ZiDongZhuangPei;
public class BlankDisc implements CompactDisc{
private String title;//歌名
private String artist;//作者
public BlankDisc(String title,String artist){
this.title=title;
this.artist=artist;
}
public void play() {
System.out.println("play:"+title+" by:"+artist);
}
}
这里的歌名和作者都是字符型,也没有明确值。但在声明bean的时候需要将值注入进去,xml的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="cd_1" class="com.zwq.ZiDongZhuangPei.BlankDisc">
<constructor-arg value="告白气球"/>
<constructor-arg value="周杰伦"/>
</bean>
</beans>
这里使用constructor-arg元素进行构造器参数注入,这次没有使用ref属性来引用其他的bean,而是使用了value属性,通过这个属性表名给定的值要以字面量的形式注入到构造其中。如果使用c-命名空间的话,格式如下:
<bean id="cd_2" class="com.zwq.ZiDongZhuangPei.BlankDisc"
c:title="告白气球"
c:artist="周杰伦"
/>
或者
<bean id="cd_2" class="com.zwq.ZiDongZhuangPei.BlankDisc"
c:_0="告白气球"
c:_1="周杰伦"
/>
这里通过命名空间装配字面量与装配引用的区别就是去掉了“-ref”后缀
2).构造器注入之装配集合
当构造器中的参数为集合是装配方式之怎样的呢,看下面这个例子
package com.zwq.ZiDongZhuangPei;
import java.util.List;
public class WhiteDisc implements CompactDisc{
private String title;//专辑名
private String artist;//作者
private List<String> tracks;//歌名
public WhiteDisc(String title, String artist, List<String> tracks) {
super();
this.title = title;
this.artist = artist;
this.tracks = tracks;
}
public void play() {
System.out.println("playing:"+title+"by:"+artist);
for(String track:tracks){
System.out.println("-Track:"+track);
}
}
}
xml配置格式如下
<bean id="cd_3" class="com.zwq.ZiDongZhuangPei.WhiteDisc">
<constructor-arg value="jay"/>
<constructor-arg value="周杰伦"/>
<constructor-arg>
<list>
<value>黑色幽默</value>
<value>可爱女人</value>
<value>龙卷风</value>
<value>反方向的钟</value>
<value>星晴</value>
</list>
</constructor-arg>
</bean>
其中list元素是constructor-arg的子元素,这表明一个包含之的列表会传递到构造器中。其中value元素用来指定列表中的每个元素也可以使用ref元素来进行bean引用列表的装配。假如有一个类它的构造器如下:
public Disc(String title,String artist,list< BlankDisc > cds){…}
那么xml的配置格式如下:
<bean id="cd_3" class="com.zwq.ZiDongZhuangPei.WhiteDisc">
<constructor-arg value="jay"/>
<constructor-arg value="周杰伦"/>
<constructor-arg>
<list>
<ref bean=“Bd1”/>
<ref bean=“Bd2”/>
<ref bean=“Bd3”/>
<ref bean=“Bd4”/>
<ref bean=“Bd5”/>
</list>
</constructor-arg>
</bean>
如果要装配成set集合的话将list元素换成set元素即可,但是所有的重复的值都会被忽略掉,存放顺序也不会得到保证。