XML 装配
新项目不怎么用了XML 来进行配置了,但是在对老项目进行维护时,还是需要的。
在resource 中新建Spring XML 文件,我们一般把这个文件命名为ApplicaContext。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 我们一般根据需要在下方声明xml 命名空间,或者xsd 文件
<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">
<!-- 这里的Bean元素就相当于注解当中的@Bean,id属性可以被替换为name属性,二者都是给类命名的作用,不同的是,name属性可以给Bean元素起多个名字 name="daf sdf;sdf,dfa" 中间用空格、分号、逗号分隔。-->
<bean id="service" class="hello.MessageService"></bean>
<bean id="printer" class="hello.MessagePrinter">
<property name="messageService" ref="service"></property>
</bean>
</beans>
这里有对bean元素的详细说明,包括使用方法
依赖注入
- 注入方式有3 中
- 构造函数注入
- c-名称空间注入
- <property> 属性注入
- p-名称空间注入(在最后面)
构造函数注入
- <constructor-arg>元素
- 需要有一个有参数的构造函数,之后再配置<constructor-arg>元素,<constructor-arg>元素是对构造函数中参数的注入,没有相应的构造函数则不能使用<constructor-arg>(可以改一下构造函数中参数的类型来验证一下,自己去试)
public MessagePrinter(MessageService messageService) {
this.messageService = messageService;
}
<bean name="service" class="hello.MessageService">
</bean>
<bean id="printer" class="hello.MessagePrinter">
<!-- 这里的ref 指定的就是将哪个个Bean对象传给相应的有参构造函数-->
<constructor-arg ref="service"/>
</bean>
c-名称空间,同样需要有参构造函数,这里同样使用上面刚提到的构造函数。
- 首先需要在XML 文件中引入c 的名称空间,和其他的xmlns 放在一起就可以
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="service" class="hello.MessageService">
</bean>
<bean id="printer" class="hello.MessagePrinter" c:messageService-ref="service">
<!-- 也可以是c:_0-ref="service" c 表示命名空间,_0表示参数在参数列表中的位置 -ref表示依赖注入,后面的字符串就是被注入的Bean 对象-->
</bean>
</beans>
<property> 属性
<property> 是对成员属性的注入,需提前设置set 函数,建议直接 Alt + Ins 生成默认的set 函数
<bean id="printer" class="hello.MessagePrinter" c:_0-ref="service">
<property name="word" value="i love you"/>
<!-- 如果注入目标是复杂数据类型,将value 换为ref,并提前设置被 “ref”对象的Bean-->
</bean>
这里需要说明,<property> 中的name 不是值成员变量的名字,而是类属性的名字。
属性的定义规则是:set/get方法名,去掉set/get后,将剩余部分首字母小写得到的字符串就是这个类的属性。这里的set/get方法指的是set/get 成员变量的函数。下面是一个例子
// userDao 是成员变量
// setUserDao 的方法名可以修改为setAAAA,对应的属性名变为aAAA。
// 参数不能多也不能少,且类型一定要和成员变量对应
public void setUserDao(UserDao userDao) {
// 这里可以添加自己的代码,但是下面这行代码不能删
this.userDao = userDao;
}
public UserDao getUserDao() {
return userDao;
}
各种数据类型的注入
- 简单类型的数据注入,String,注意在对应类中要有相应的构造函数。
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="printer" class="hello.MessagePrinter">
<!-- 注意这里有三种方式-->
<!-- 第一种-->
<!--<constructor-arg value="ligang"/>-->
<!--<constructor-arg value="fanbinbin"/>-->
<!--第二种-->
<!--<constructor-arg name="brother" value="ligang"/>-->
<!--<constructor-arg name="sister" value="fanbinbin"/>-->
<!-- 第三种-->
<constructor-arg index="0" value="ligang"/>
<constructor-arg index="1" value="fanbinbin"/>
</bean>
</beans>
或者c-名称空间
<bean id="printer" class="hello.MessagePrinter" c:brother="ligang" c:sister="fanbinbin"/>
<!-- 或者 -->
<!-- <bean id="printer" class="hello.MessagePrinter" c:_0="ligang" c:_1="fanbingbing"/>-->
- list 类型注入,list、set、map 都无法使用c-名称空间。
<bean id="printer" class="hello.MessagePrinter" c:_0-ref="service">
<constructor-arg name = "list">
<list>
<!-- 这里list中的元素是字符串 -->
<value>i love you</value>
<value>i love she</value>
<!-- 像上面那样重复就可以-->
<!-- 如果list 中的元素是复杂类型怎么办?-->
</list>
</constructor-arg>
</bean>
如果list 中的元素是复杂类型
<!-- 这里一定要对将要添加到list中的element元素添加Bean 元素-->
<bean id="element1" class="hello.word"></bean>
<bean id="element2" class="hello.word"></bean>
<bean id="element3" class="hello.word"></bean>
<bean id="printer" class="hello.MessagePrinter" c:_0-ref="service">
<constructor-arg name = "list">
<list>
<!--list 中元素为复杂类型时,不能再使用 value来添加元素-->
<ref bean="element1"/>
<ref bean="element2"/>
<ref bean="element3"/>
<!-- 像上面那样重复就可以-->
</list>
</constructor-arg>
</bean>
同样的,如果是对set 类型对象装入时,只需将<list> 换为 <set> 即可。
注意,set 中的元素时互异的,就是说无法添加两个完全相同的元素。本来set 也是无序的,但是这里默认使用的LinkHashSet,所以是有序的。
- map 类型注入
<!-- 这里一定要对将要添加到list中的element元素添加Bean 元素-->
<bean id="element1" class="hello.word"></bean>
<bean id="element2" class="hello.word"></bean>
<bean id="element3" class="hello.word"></bean>
<bean id="printer" class="hello.MessagePrinter" c:_0-ref="service">
<constructor-arg name = "map">
<map>
<!--如果map 的value 值是String 的话,也可以直接用value-->
<entry key="e1" value-ref="element1"/>
<entry key="e1" value-ref="element1"/>
<entry key="e1" value-ref="element1"/>
<!-- 像上面那样重复就可以-->
</map>
</constructor-arg>
</bean>
- 数组的注入,String[] 这种
<!-- 这里一定要对将要添加到list中的element元素添加Bean 元素-->
<bean id="element1" class="hello.word"></bean>
<bean id="element2" class="hello.word"></bean>
<bean id="element3" class="hello.word"></bean>
<bean id="printer" class="hello.MessagePrinter" c:_0-ref="service">
<constructor-arg name = "array">
<array>
<!--String[] 和基本数据类型的数组-->
<value>i love you </value>
<!--复杂数据类型的数组-->
<ref bean="element1"/>
<ref bean="element2"/>
<ref bean="element3"/>
<!-- 像上面那样重复就可以-->
</array>
</constructor-arg>
</bean>
- 总结上面的代码,可以发现String 及基本数据类型赋值时用的都是value。而对复杂数据类型,使用的都是ref 或者-ref(reference:引用),并且都需要提前设置被 “ref”对象的Bean。这对下面的<property>配置同样适用。
- <property>对数组、list、set、map数据类型的注入,与<constructor>的注入方式基本一致,这里只举一个例子。
<!-- 这里一定要对将要添加到list中的element元素添加Bean 元素-->
<bean id="element1" class="hello.word"></bean>
<bean id="element2" class="hello.word"></bean>
<bean id="element3" class="hello.word"></bean>
<bean id="printer" class="hello.MessagePrinter" c:_0-ref="service">
<property name = "array">
<array>
<!--String[] 和基本数据类型的数组-->
<value>i love you </value>
<!--复杂数据类型的数组-->
<ref bean="element1"/>
<ref bean="element2"/>
<ref bean="element3"/>
<!-- 像上面那样重复就可以-->
</property>
</constructor-arg>
</bean>
- 还可以使用p 名称空间注入。数组、list、set、map数据类型的注入不能使用p 名称空间
- p 名称空间同样需提前设置set 函数。
<!-- 首先在上方添加p 命名空间,具体语句如下-->
<!--xmlns:c="http://www.springframework.org/schema/c"-->
<bean id="printer" class="hello.MessagePrinter" p:brother="XiaoGeGe">
<!-- 如果注入目标是复杂数据类型,将value 换为-ref,并提前设置被 “ref”对象的Bean-->
</bean>
- 要想使用p 名称空间注入数组、list、set、map,需要结合使用util
- util 的名称空间声明挺复杂,可以直接在下面输入<util:list>,然后让idea 自己为我们导入
数组、List数据类都是使用的都是util:list
set、map使用的分别是util:set、util:map
<util:list name="littlelist">
<ref bean="element1"/>
<ref bean="element2"/>
<ref bean="element3"/>
</util:list>
<!-- 之后在下面的bean 节点中添加p 节点。-->
<bean id="printer" class="hello.MessagePrinter" p:list="littlelist"></bean>