上一篇文章我们讲了如何使用Java告诉Spring怎么装配Bean,这章讲解一下一个古老的方式,也就是通过XML装配Bean,为什么称它古老呢,因为最开始的Spring版本都是通过XML进行装配的,虽然古老,但是我们还是要讲解一下它,毕竟很多老项目都是使用了XML配置。
XML配置规范
在JavaConfig时,我们需要以@Configuration标识某个类作为我们的类,然后在这个类中定义我们的Bean,而通过XML进行配置就稍微复杂了一些,我们的XML的配置文件要以<beans>
元素为根,比如:
<?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">
<--配置我们的bean-->
</beans>
声明一个Bean
元素<bean>
相当于JavaConfig里的@Bean,我们什么一个Bean
<bean class="TelePhone"/>
在这里我们没有明确指定这个Bean的ID,它自动得到的ID是类的权限名加上“#”和索引,比如我们这个ID就是”TelePhone#0”,所以一般情况下我们需要定义这个ID:
比如: <bean name="phone" class="TelePhone"/>
这样我们的ID就为”phone”。
注入Bean
注入Bean的方式要Bean对应的代码的形式,可以有以下几种方式:
1. 构造器注入。
2. setter(其他参数为Bean类的方法)方式注入。
构造器注入
虽然构造器注入也有两种方式:
1. 使用<constructor-arg>
元素。
2. 使用Spring 3.0所引入的c-命名空间。
但是我个人喜欢使用前者,虽然后者比前者更简练,但是不好记,不直观。
比如我们的类有个构造方法:
public ChaneseHuman(Phone phone){
this.phone = phone;
}
我们注入的方式:
<bean name="human" class="ChaneseHuman">
<constructor-arg ref="phone"/>
</bean>
setter方法注入
我们的Java代码:
public void setPhone(Phone phone) {
this.phone = phone;
}
XML配置代码:
<bean name="human" class="ChaneseHuman">
<property name="phone" ref="phone"/>
</bean>
引用其他类型的Bean
我们上面的例子只引用了一个普通的Object,如果要引用List、Set等,这些怎么处理呢?
Spring util-XXX是我们的选择。
元 素 | 描 述 |
---|---|
<util:constant> | 引用某个类型的public static域,并将其暴露为bean |
util:list | 创建一个java.util.List类型的bean,其中包含值或引用 |
util:map | 创建一个java.util.Map类型的bean,其中包含值或引用 |
util:properties | 创建一个java.util.Properties类型的bean |
util:property-path | 引用一个bean的属性(或内嵌属性),并将其暴露为bean |
util:set | 创建一个java.util.Set类型的bean,其中包含值或引用 |
下面我们一一举例来描述一下这些元素怎么使用。
<util:constant>
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: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.xsd">
<util:constant static-field="TestMain.VALUE" id="value"/>
</beans>
Java代码:
public class TestMain {
public static final String VALUE = "我是一个常量";
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/pen.xml");
String s = (String)applicationContext.getBean("value");
System.out.println(s);
}
}
打印结果: 我是一个常量
。
为了减少篇幅,后面我讲省略声明部分,只贴出核心部分。
<util:list>
xml配置:
<util:list id="list" list-class="java.util.ArrayList" value-type="java.lang.String">
<value>AA</value>
<value>BB</value>
<value>CC</value>
<value>DD</value>
</util:list>
java代码:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/pen.xml");
List<String> s = (List<String>) applicationContext.getBean("list");
for(String str:s) {
System.out.println(str);
}
输出结果:
AA
BB
CC
DD
<util:set>
xml配置:
<util:set id="set" value-type="java.lang.String">
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
<value>DDD</value>
</util:set>
java代码:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/pen.xml");
Set<String> set = (Set<String>) applicationContext.getBean("set");
for(String s:set){
System.out.println(s);
}
输出结果:
AAA
BBB
CCC
DDD
<util:map>
xml代码:
<util:map id="map" map-class="java.util.HashMap" value-type="java.lang.String" key-type="java.lang.String">
<entry key="a" value="aaa"/>
<entry key="b" value="bbb"/>
<entry key="c" value="ccc"/>
</util:map>
java代码:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/pen.xml");
Map<String, String> v = (Map<String, String>) applicationContext.getBean("map");
v.forEach((key, value) -> {
System.out.println("key: " + key + ", value: " + value);
});
打印结果:
key: a, value: aaa
key: b, value: bbb
key: c, value: ccc
<util:properties>
首先在resources/config下建立一个test.properties文件,内容如下:
aaa=1
bbb=2
ccc=3
配置xml:
<util:properties id="properties" location="config/test.properties">
</util:properties>
Java代码:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/pen.xml");
Properties properties = (Properties) applicationContext.getBean("properties");
System.out.println(properties.getProperty("aaa"));
System.out.println(properties.getProperty("bbb"));
System.out.println(properties.getProperty("ccc"));
执行结果:
1
2
3
<util:property-path>
这个元素的作用是将指定Bean的指定属性以Bean的形式暴露出来。
写个类:
Student
public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
xml配置
<bean id="student" class="Student">
<property name="name">
<value>飛哥</value>
</property>
</bean>
<util:property-path path="student.name" id="name"/>
main代码:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/pen.xml");
String name = (String)applicationContext.getBean("name");
System.out.println(name);
打印结果:
飛哥