Spring配置的混合使用
在之前的文章中(Spring中的Bean装配|学习笔记 (syuez.com))讲了 Spring 的自动装配,但是有时候不得不使用 XML 配置。本文将简单介绍一下 Java 配置和 XML 配置混合使用的情景。
在之前定义的 SgtPeppers 唱片中只包含了唱片名称和艺术家的名字。如果现实世界中的 CD 也是这样的话,那么在技术上就不会任何的进展。CD 之所以值得购买是因为它上面所承载的音乐。大多数的 CD 都会包含十多个磁道,每个磁道上包含一首歌。
如果使用 CompactDisc 为真正的 CD 建模,那么它也应该有磁道列表的概念。请考虑下面这个新的 BlankDisc:
import java.util.List;
public class BlankDisc implements CompactDisc {
private String title;
private String artist;
private List<String> tracks; // 磁道,CD 都会包含十多个磁道,每个磁道上包含一首歌
public BlankDisc(String title, String artist, List<String> tracks) {
this.title = title;
this.artist = artist;
this.tracks = tracks;
}
@Override
public void play() {
System.out.println("Playing " + title + " by " + artist);
for (String track : tracks) {
System.out.println("-Track: " + track);
}
}
}
这个变更会对 Spring 如何配置 bean 产生影响,在声明 bean 的时候,我们必须要提供一个磁道列表。最简单的办法是将列表设置为 null,将 null 传递给构造器。因为它是一个构造器参数,所以必须要声明它。
这并不是解决问题的好办法,虽然在注入期它能正常执行。但当调用 play() 方法时,你会遇到 NullPointerException 异常,因此并不是理想的方案。
更好的解决方法是提供一个磁道名称的列表。在 resources 目录中创建 Spring XML 配置文件 blank-disc.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="blankDisc" class="com.syuez.BlankDisc" primary="true">
<constructor-arg index="0" value="Sgt. Pepper's Lonely Hearts Club Band" />
<constructor-arg index="1" value="The Beatles" />
<constructor-arg index="2">
<list>
<value>Sgt. Pepper's Lonely Hearts Club Band</value>
<value>With a Little Help from My Friends</value>
<value>Lucy in the Sky with Diamonds</value>
<value>Getting Better</value>
<value>Fixing a Hole</value>
</list>
</constructor-arg>
</bean>
</beans>
由于此处存在多个符合 CDPlayer 自动注入的 CompactDisc 类,所以添加了 primary 标签来标示首选的 bean。
接着要使 blank-disc.xml 生效,在 CDPlayerConfig 中添加 @ImportResource 注解:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
/**
* CD配置类
*/
@Configuration
@ComponentScan
@ImportResource({"classpath*:blank-disc.xml"})
public class CDPlayerConfig {
}
重新运行 CDPlayerTest 测试,看是否通过

参考链接:
Spring 自动装配,Java 配置,XML配置、混合使用 - 程序员文章站 (superweb999.com)
Spring @ImportResource Annotation Example (javaguides.net)
详解Spring项目中的classpath路径_Allen Chou的博客-CSDN博客_spring获取classpath路径
What is the alternative of using @Qualifier annotation in XML in Spring? - Stack Overflow
Java / Spring: "Tagging" beans in XML to get specific bean by class and tag - Stack Overflow