Spring如今有了强大的自动化配置和基于Java的配置,XML不该该再是你的第一选择了。不过,鉴于已经存在那么多基于XML的Spring配置,因此理解如何在Spring中使用XML仍是很重要的。可是,我但愿本节的内容只是用来帮助你维护已有的XML配置,在完成新的Spring工做时,但愿你会使用自动化配置和JavaConfig。java
在使用XML为Spring装配bean以前,你须要建立一个新的配置规范。在使用JavaConfig的时候,这意味着要建立一个带有@Configuration注解的类,而在XML配置中,这意味着要建立一个XML文件,而且要以<beans>元素为根。spring
最为简单的Spring XML配置以下所示:数组
很容易就能看出来,这个基本的XML配置已经比同等功能的JavaConfig类复杂得多了。做为起步,在JavaConfig中所须要的只是@Configuration,但在使用XML时,须要在配置文件的顶部声明多个XML模式(XSD)文件来约束格式,这些文件定义了配置Spring的XML元素。函数
要在基于XML的Spring配置中声明一个bean,咱们要使用spring-beans模式中的另一个元素:<bean>。<bean>元素相似于JavaConfig中的@Bean注解。测试
咱们能够按照以下的方式声明CompactDiscbean:spa
这里声明了一个很简单的bean,建立这个bean的类经过class属性来指定的,它将会调用SgtPeppers的默认构造器来建立bean,而且要使用全限定的类名。借助id属性,为每一个bean设置一个名字(在装配到其余bean的时须要根据准确的名字)。
补充:限定类名,就是类名全称,带包路径的用点隔开,例如: java.lang.String。非限定(non-qualified)类名也叫短名,就是咱们平时说的类名,不带包的,例如:String。3d
在Spring XML配置中,只有一种声明bean的方式:使用<bean>元素并指定class属性。Spring会从这里获取必要的信息来建立bean。可是,在XML中声明DI时,会有多种可选的配置方案和风格。具体到构造器注入,有两种基本的配置方案可供选择:对象
接下来,看一下它们各自如何注入bean引用。blog
例子场景:建立一个CDPlayer(CD播放器)的bean,须要有一个接收CompactDisc(CD盘)类型的构造器。it
当Spring遇到这个<bean>元素时,它会建立一个CDPlayer实例。<constructor-arg>元素会告知Spring要将一个ID为compactDisc的bean引用传递到CDPlayer的构造器中。
做为替代的方案,你也可使用Spring的c-命名空间。c-命名空间是在Spring 3.0中引入的,它是在XML中更为简洁地描述构造器参数的方式。要使用它的话,必需要在XML的顶部声明其模式,以下所示:
在c-命名空间和模式声明以后,咱们就可使用它来声明构造器参数了,以下所示:
配置结构图:(这里粗略的讲解c-命名空间)
补充:字面量就是值 不声明变量储存。例如 int a = 0; a = a + 3; a 是变量 3是字面量;
CompactDisc的一个新实现,有参构造函数的参数是基本类型(直接传字面量)而不是对象的引用时:
XML的配置:
c-命名空间:
在装配bean引用和字面量值方面,<constructor-arg>和c-命名空间的功能是相同的。可是有一种状况是<constructor-arg>可以实现,c-命名空间却没法作到的。接下来,让咱们看一下如何将集合装配到构造器参数中。
需求:若是使用CompactDisc为真正的CD建模,那么它也应该有磁道列表(tracks)的概念,每一个磁道上包含一首歌。请考虑下面这个新的BlankDisc:
在声明bean的时候,咱们必需要提供一个磁道列表。要达到这一点,咱们能够有多个可选方案。首先,可使用<list>元素将其声明为一个列表:
其中,<list>元素是<constructor-arg>的子元素,这代表一个包含值的列表将会传递到构造器中。其中,<value>元素用来指定列表中的每一个元素。
与之相似,咱们也可使用<ref>元素替代<value>,实现bean引用列表的装配。例如,假设你有一个Discography类,它的构造器以下所示(集合泛型为对象引用):
那么,你能够采起以下的方式配置Discography bean:
当构造器参数的类型是java.util.List时,使用<list>元素是合情合理的。尽管如此,咱们也能够按照一样的方式使用<set>元素:
<set>和<list>元素的区别不大,其中最重要的不一样在于当Spring建立要装配的集合时,所建立的是java.util.Set仍是java.util.List。若是是Set的话,全部重复的值都会被忽略掉,存放顺序也不会得以保证。不过不管在哪一种状况下,<set>或<list>均可以用来装配List、Set甚至数组。
到目前为止,CDPlayer和BlankDisc类彻底是经过构造器注入的,没有使用属性的Setter方法。接下来,咱们就看一下如何使用Spring XML实现属性注入。假设属性注入的CDPlayer以下所示:
该选择构造器注入仍是属性注入呢?做为一个通用的规则,我倾向于对强依赖使用构造器注入,而对可选性的依赖使用属性注入。如今,CDPlayer没有任何的构造器(除了隐含的默认构造器),它也没有任何的强依赖。所以,你能够采用以下的方式将其声明为
Spring bean:
Spring在建立bean的时候不会有任何的问题,可是CDPlayerTest会由于出现NullPointerException而致使测试失败,由于咱们并无注入CDPlayer的compactDisc属性。不过,按照以下的方式修改XML,就能解决该问题
<property>元素为属性的Setter方法所提供的功能与<constructor-arg>元素为构造器所提供的功能是同样的。在本例中,它引用了ID为compactDisc的bean(经过ref属性),并将其注入到compactDisc属性中(经过setCompactDisc()方法)
Spring为<constructor-arg>元素提供了c-命名空间做为替代方案,与之相似,Spring提供了更加简洁的p-命名空间,做为<property>元素的替代方案。为了启用p-命名空间,必需要在XML文件中与其余的命名空间一块儿对其进行声明:
咱们可使用p-命名空间,按照如下的方式装配compactDisc属性:
p-命名空间中属性所遵循的命名约定与c-命名空间中的属性相似。
属性也能够注入字面量,这与构造器参数很是相似。做为示例,咱们从新看一下BlankDisc bean,新的BlankDisc类以下所示:
咱们须要装配这些属性,能够借助<property>元素的value属性实现该功能:
在这里,除了使用<property>元素的value属性来设置title和artist,咱们还使用了内嵌的<list>元素来设置tracks属性;另一种可选方案就是使用p-命名空间的属性来完成该功能:
与c-命名空间同样,装配bean引用与装配字面量的惟一区别在因而否带有“-ref”后缀。若是没有“-ref”后缀的话,所装配的就是字面量。
咱们不能使用p-命名空间来装配集合,没有便利的方式使用p-命名空间来指定一个值(或bean引用)的列表。可是,咱们可使用Spring util-命名空间中的一些功能来简化BlankDiscbean。(不作详细说明)