在上一篇中,遇到了一些问题,其实这些问题,是因为对Spring不熟悉,用的太少才会有的问题,我觉得有一些是理解上的问题,这一篇说通过XML装配bean,
有这么一句话:bean元素类似于javaconfig中的@Bean注解,其实看到这里基本上也就明白上一篇中的问题了。下面来具体看:
- 构造器注入初始化Bean:
–>构造器注入bean引用
上面的代码也比较简单,就不做多说了。
–>将字面量注入到构造器中
现在有一个这样的CompactDisc的实现类:BlankDiscXML.java
所以这个时候我们可以在.xml中这么写:
<bean id="blankDisc" class="com.stanxu.xmlconfig.BlankDiscXML">
<constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band"> </constructor-arg>
<constructor-arg value="The Beatles"></constructor-arg>
</bean>
–> 装配集合
一张CD上面会包含很多的轨道,从而可以放很多歌曲,修改一下BlankDiscXML.java
package com.stanxu.xmlconfig;
import java.util.List;
import com.stanxu.soundsystem.CompactDisc;
public class BlankDiscXML implements CompactDiscXML {
private String title;
private String artist;
private List<String> tracks;
public BlankDiscXML(String title, String artist,List<String> tracks) {
// TODO Auto-generated constructor stub
this.title = title;
this.artist = artist;
this.tracks = tracks;
}
public void play() {
// TODO Auto-generated method stub
System.out.print("Playing " + title + " by " + artist);
for(String track : tracks){
System.out.println("-Track: " + track);
}
}
}
那么这个时候我们在XML中应该这么写了:
<bean id="blankDisc" class="com.stanxu.xmlconfig.BlankDiscXML">
<constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band"></constructor-arg>
<constructor-arg value="The Beatles"></constructor-arg>
<constructor-arg>
<list>
<value>Sgt. Pepper's Lonely Hearts Club Band</value>
<value>With a Little Help from My Friends</value>
<value>Getting Better</value>
</list>
</constructor-arg>
</bean>
这都没有什么不好理解的,如果是List中元素是引用类型的话,就直接把value换成ref就可以了。像:
<ref bean="xxx" />
当然也可以用Set集合来代替List,但是有重复的都会被忽略掉,顺序也不能保证,这都是问题。
- setter方法注入
关于何时使用构造器注入,何是使用setter方法注入,因具体情况而定,一般一些强依赖关系使用构造器注入,而弱依赖使用setter方法注入。
package com.stanxu.xmlconfig;
public class CDPlayerXML implements MediaPlayerXML {
private CompactDiscXML discXML;
public CDPlayerXML(CompactDiscXML discXML) {
// TODO Auto-generated constructor stub
this.discXML = discXML;
}
public void play(){
discXML.play();
}
}
在XML中对应的是:
<bean id="compactDiscXML" class="com.stanxu.xmlconfig.CompactDiscXML"></bean>
<bean id="cdPlayerXML" class="com.stanxu.xmlconfig.CDPlayerXML">
<property name="discXML" ref="compactDiscXML"></property>
</bean>
将字面量注入到属性中,修改一下BlankDiscXML.java,要达到的效果是一样的。
package com.stanxu.xmlconfig;
import java.util.List;
import com.stanxu.soundsystem.CompactDisc;
public class BlankDiscXML implements CompactDisc {
private String title;
private String artist;
private List<String> tracks;
// public BlankDiscXML(String title, String artist,List<String> tracks) {
// // TODO Auto-generated constructor stub
// this.title = title;
// this.artist = artist;
// this.tracks = tracks;
// }
public void setTitle(String title){
this.title = title;
}
public void setArtist(String artist){
this.artist = artist;
}
public void setTracks(List<String> tracks){
this.tracks = tracks;
}
public void play() {
// TODO Auto-generated method stub
System.out.print("Playing " + title + " by " + artist);
for(String track : tracks){
System.out.println("-Track: " + track);
}
}
}
在xml中对应是这样的:
<bean id="blankDisc" class="com.stanxu.xmlconfig.BlankDiscXML">
<!-- <constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band"></constructor-arg> -->
<!-- <constructor-arg value="The Beatles"></constructor-arg> -->
<!-- <constructor-arg> -->
<!-- <list> -->
<!-- <value>Sgt. Pepper's Lonely Hearts Club Band</value> -->
<!-- <value>With a Little Help from My Friends</value> -->
<!-- <value>Getting Better</value> -->
<!-- </list> -->
<!-- </constructor-arg> -->
<property name="title" value="Sgt. Pepper's Lonely Hearts Club Band"></property>
<property name="artist" value="The Beatles"></property>
<property name="tracks">
<list>
<value>Sgt. Pepper's Lonely Hearts Club Band</value>
<value>With a Little Help from My Friends</value>
<value>Getting Better</value>
</list>
</property>
</bean>
上面看上去比较的冗余,可以利用Spring util-命名空间中的一些功能来简化BlankDisc bean,像下面这样:
那么接下来把自动化配置、javaConfig、以及XML配置混合使用:
现在是这样,BlankDiscXML从CDPlayerConfigXML.java中分离出来,定义到它自己的CDConfig.java中:
package com.stanxu.xmlconfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CDConfigXML {
@Bean
public CompactDiscXML compactDiscXML(){
return new BlankDiscXML();
}
}
这里稍后会改成在XML中配置。
现在CDPlayerConfigXML.java中就只有CDPlayerXML.java:
现在是这样,这样分开之后 ,可以用下面这种方法再把它们合起来的:新建一个SouldSystemConfig.java:
不用@Bean的方式来去注入SgtPeppersXML,而是把它放到XML中配置
package com.stanxu.xmlconfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
@Configuration
@Import(CDPlayerXMLConfig.class)
@ImportResource("classpath:spring.xml")
public class SoundSystemConfig {
}
spring.xml:
<util:list id="trackList">
<value>Sgt. Pepper's Lonely Hearts Club Band</value>
<value>With a Little Help from My Friends</value>
<value>Getting Better</value>
</util:list>
<bean id="blankDisc" class="com.stanxu.xmlconfig.BlankDiscXML">
<property name="title" value="Sgt. Pepper's Lonely Hearts Club Band"></property>
<property name="artist" value="The Beatles"></property>
<property name="tracks" ref="trackList"></property>
</bean>
所以到这里就实现了,在javaconfig中引用XML配置。