概述:
初学者用到spring的时候自然想到用xml配置文件,xml几乎是spring实现代名词
主要学习点:
1.构造器注入。
2.属性注入
1.构造器注入
- <constructor-arg>元素
- 使用Spring3.0所引入的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:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- <bean id="adeleSong" class="learn.chapter2.AdeleSong" /> -->
<!-- <bean id="girlSong" class="learn.chapter2.GirlSong"> <constructor-arg
ref="adeleSong"/> </bean> -->
<!-- c命名空间来 -->
<!-- <bean id="girlSong" class="learn.chapter2.GirlSong"
c:compactDisc-ref="adeleSong" /> -->
<!-- c命名空间来 可以用索引,不过前面必须要下划线,因为不能以数字开头-->
<!-- <bean id="girlSong" class="learn.chapter2.GirlSong" c:_0-ref="adeleSong" /> -->
<!-- c命名空间来 如果是一个参数的构造方法可以省略索引-->
<!-- <bean id="girlSong" class="learn.chapter2.GirlSong" c:_-ref="adeleSong" />
-->
<!-- <bean id="adeleSong" class="learn.chapter2.AdeleSong">
<constructor-arg value="hellossssss"></constructor-arg>
<constructor-arg value="Adeleeeee"></constructor-arg>
</bean> -->
<!-- <bean id="adeleSong" class="learn.chapter2.AdeleSong"
c:title="hellossssssss"
c:artist="Adeleeeeee"
/> -->
<bean id="adeleSong" class="learn.chapter2.AdeleSong"
c:_0="hellossssssss"
c:_1="Adeleeeeee"
/>
</beans>
package learn.chapter;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import learn.chapter2.AdeleSong;
import learn.chapter2.GirlSong;
import learn.chapter2.javaConfig.CDPlayerConfig;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class XMLClearTest2 {
@Test
public void CompactDiscIsNotNull(){
ApplicationContext ac = new ClassPathXmlApplicationContext("constructor.xml");
assertNotNull(ac.getBean("girlSong"));
GirlSong girl = (GirlSong) ac.getBean("girlSong");
girl.getCompactDisc().play();
}
@Test
public void CompactDisc(){
ApplicationContext ac = new ClassPathXmlApplicationContext("constructor.xml");
assertNotNull(ac.getBean("adeleSong"));
AdeleSong girl = (AdeleSong) ac.getBean("adeleSong");
girl.play();
}
}
package learn.chapter2;
import org.springframework.stereotype.Component;
/**
* 创建一个Adele的歌曲hello
* @author Administrator
*
*/
@Component
public class AdeleSong implements CompactDisc{
private String title = "hello";
private String artist = "Adele";
public AdeleSong() {
super();
// TODO Auto-generated constructor stub
}
public AdeleSong(String title, String artist) {
super();
this.title = title;
this.artist = artist;
}
public void play() {
System.out.println("歌曲为:" + title + "\t歌手为:" + artist);
}
}
总结:构造方法注入有三种方式
<constructor-arg value =""/>
<c:_索引-ref=Id/>
<c:构造参数名-ref=beanId/>
2.装配集合(这时候c:空间不可以装配集合)
package learn.chapter2;
import java.util.List;
public class BlankDisc implements CompactDisc {
private String title;
private String artist;
private List<String> tracks;
public BlankDisc(String title, String artist, List<String> tracks) {
super();
this.title = title;
this.artist = artist;
this.tracks = tracks;
}
public void play() {
System.out.println("专辑为" + title + "\t 歌手为:" + artist);
if(null!=tracks && tracks.size() > 0){
for (String track : tracks){
System.out.println("---磁道: " + track);
}
}
}
}
<?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"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
<!-- 容易报空指针异常 -->
<!-- <bean id="compactDisc" class="learn.chapter2.BlankDisc">
<constructor-arg value="海阔天空"></constructor-arg>
<constructor-arg value="beyond"></constructor-arg>
<constructor-arg ><null/></constructor-arg>
</bean> -->
<!-- 容易报空指针异常 -->
<bean id="compactDisc" class="learn.chapter2.BlankDisc">
<constructor-arg value="海阔天空"></constructor-arg>
<constructor-arg value="beyond"></constructor-arg>
<constructor-arg >
<list>
<value>磁道一</value>
<value>磁道二</value>
<value>磁道仨</value>
<value>磁道四</value>
<value>磁道五</value>
</list>
</constructor-arg>
</bean>
</beans>
测试类:
package learn.chapter;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import learn.chapter2.AdeleSong;
import learn.chapter2.CompactDisc;
import learn.chapter2.GirlSong;
import learn.chapter2.javaConfig.CDPlayerConfig;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class XMLClearTest2 {
@Test
public void CompactDiscIsNotNull(){
ApplicationContext ac = new ClassPathXmlApplicationContext("constructor.xml");
assertNotNull(ac.getBean("girlSong"));
GirlSong girl = (GirlSong) ac.getBean("girlSong");
girl.getCompactDisc().play();
}
@Test
public void CompactDisc(){
ApplicationContext ac = new ClassPathXmlApplicationContext("constructor.xml");
assertNotNull(ac.getBean("adeleSong"));
AdeleSong girl = (AdeleSong) ac.getBean("adeleSong");
girl.play();
}
/**
* 测试集合
*/
@Test
public void CompactDiscSet(){
ApplicationContext ac = new ClassPathXmlApplicationContext("constructor.xml");
assertNotNull(ac.getBean("compactDisc"));
CompactDisc girl = (CompactDisc) ac.getBean("compactDisc");
girl.play();
}
}
总结主要涉及到值的注入,这里可以用list 和set ,两者的区别就是list能保证顺序,而set保证唯一性
注入对象:
package learn.chapter2;
import java.util.List;
import org.springframework.stereotype.Component;
@Component
public class GirlSong {
private CompactDisc compactDisc;
private List<CompactDisc> compactDiscs;
public GirlSong(List<CompactDisc> compactDiscs) {
super();
this.compactDiscs = compactDiscs;
}
public GirlSong(CompactDisc compactDisc) {
this.compactDisc = compactDisc;
}
public CompactDisc getCompactDisc() {
return compactDisc;
}
public void setCompactDisc(CompactDisc compactDisc) {
this.compactDisc = compactDisc;
}
}
<bean id="adeleSong" class="learn.chapter2.AdeleSong"/>
<bean id="ananRyokoSong" class="learn.chapter2.AnanRyokoSong"/>
<bean id="keshaSong" class="learn.chapter2.KeshaSong"/>
<bean id="girlSong" class="learn.chapter2.GirlSong">
<constructor-arg>
<list>
<ref bean="adeleSong"/>
<ref bean="ananRyokoSong"/>
<ref bean="keshaSong"/>
</list>
</constructor-arg>
</bean>
测试方法:
/**
* 测试集合注入bean
*/
@Test
public void CompactDiscBeanSet(){
ApplicationContext ac = new ClassPathXmlApplicationContext("constructor.xml");
assertNotNull(ac.getBean("girlSong"));
GirlSong girl = (GirlSong) ac.getBean("girlSong");
List<CompactDisc> lis = girl.getCompactDiscs();
for(CompactDisc d : lis){
d.play();
}
}
结果:
歌曲为:hello 歌手为:Adele
歌曲为:Refrain 歌手为:AnanRyoko
歌曲为:Tik Tok 歌手为:Kesha
2.属性注入
属性注入跟构造方式注入很相似,对应构造有c:命名空间 属性有p:命名空间,同时提供非常有用的帮助util标签,完成组件的效果
属性注入一般用于弱依赖,也就是可有可无补充条件,而构造一般用于强依赖,也就是必要的条件
定义三个属性:
package learn.chapter2;
import java.util.List;
public class BlankDisc implements CompactDisc {
private String title;
private String artist;
private List<String> tracks;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public List<String> getTracks() {
return tracks;
}
public void setTracks(List<String> tracks) {
this.tracks = tracks;
}
@Override
public String toString() {
return "BlankDisc [title=" + title + ", artist=" + artist + ", tracks=" + tracks + "]";
}
public void play() {
System.out.println("专辑为" + title + "\t 歌手为:" + artist);
if(null!=tracks && tracks.size() > 0){
for (String track : tracks){
System.out.println("---磁道: " + track);
}
}
}
}
<?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"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 只注入两个属性 -->
<bean id="blankDisc" class="learn.chapter2.BlankDisc">
<property name="title" value="hello"/>
<property name="artist" value="adele"/>
</bean>
</beans>
测试类:
package learn.chapter;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import learn.chapter2.BlankDisc;
import learn.chapter2.javaConfig.CDPlayerConfig;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class XMLClearTest2 {
/**
* 测试集合注入bean
*/
@Test
public void CompactDiscBeanSet(){
ApplicationContext ac = new ClassPathXmlApplicationContext("constructor.xml");
assertNotNull(ac.getBean("blankDisc"));
BlankDisc girl = (BlankDisc) ac.getBean("blankDisc");
System.out.println(girl);
}
}
结果:
BlankDisc [title=hello, artist=adele, tracks=null]
接下来用p空间来设置,首先要添加命名空间的头部 xmlns:p="http://www.springframework.org/schema/p"
<?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"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
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.xsd">
<!-- 只注入两个属性 -->
<!-- <bean id="blankDisc" class="learn.chapter2.BlankDisc">
<property name="title" value="hello"/>
<property name="artist" value="adele"/>
</bean>
-->
<!-- 只注入两个属性 采用p空间-->
<bean id="blankDisc" class="learn.chapter2.BlankDisc"
p:title="hello"
p:artist="adele"/>
</beans>
测试的结果是一样的。注意如果是字面值不用-ref,反之
通过属性配置集合
<!-- 用属性配置集合,这时候只能有property属性 -->
<bean id="blankDisc" class="learn.chapter2.BlankDisc">
<property name="title" value="hello" />
<property name="artist" value="adele" />
<property name="tracks">
<list>
<value>磁道1</value>
<value>磁道2</value>
<value>磁道3</value>
</list>
</property>
</bean>
结果为:
BlankDisc [title=hello, artist=adele, tracks=[磁道1, 磁道2, 磁道3]]
通过帮助命名空间:增加头信息
xmlns:util="http://www.springframework.org/schema/util"
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
<?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"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!-- property帮助标签 util,首先要引入命名空间 -->
<!-- 它可以将list单独分开出来,其它bean可以复用 -->
<util:list id="trackList">
<value>磁道1</value>
<value>磁道2</value>
<value>磁道3</value>
</util:list >
<util:map>
<entry key="">
<value></value>
</entry>
</util:map>
<bean id="blankDisc"
class="learn.chapter2.BlankDisc"
p:title="hello"
p:artist="adele"
p:tracks-ref="trackList"></bean>
</beans>
测试的效果是一样的
其它所有的标签
- 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标签,方便复用