Spring提供了三种装配的机制:
- 自动化装配Bean
- 通过Java进行显式配置
- 在XML中进行配置
1.自动化装配bean
Spring从两个方面来实现自动化装配:
- 组件扫描(component scanning):Spring会自动发现应用上下文中创建的bean
- 自动装配(auto wiring):Spring自动满足bean之间的依赖
以下以一个CD播放器的概念展现自动化装配bean的过程
1.1 创建可被发现的bean
用CompactDisc接口定义CD的概念
package com.junzerg.player_autoconfig;
public interface CompactDisc {
void play();
}
1.2 带有@Component注解的CompactDisc实现类SgtPeppers
package com.junzerg.player_autoconfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer implements MediaPlayer {
private CompactDisc cd;
@Autowired
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
public void play() {
cd.play();
}
}
-
@Component注解
- @Component注解表明该类会作为组件类,并告知Spring要为这个类创建bean
- 默认bean的ID名为类名首字母变成小写,可以通过@Component为bean设置自定义ID:
@Component("theId")
-
@Autowired注解声明自动装配,该注解可以用在类的任何方法,主要是构造器方法,和Setter方法上。Spring都会尝试满足方法参数上所声明的依赖。
- 如果有一个bean匹配依赖需求,这个bean会被装配进来
- 如果没有匹配的bean,在应用文创建的时候,Spring会抛出一个异常。可以通过设置@AutoWired注解的required属性值为false来避免异常的出现。这时,Spring尝试执行自动装配,但是如果没有匹配的bean,Spring会让这个bean处于未装配的状态,有可能出现NullPointerException异常。
- 如果有多个bean能满足依赖关系,Spring会抛出一个异常,这里可以添加一个自动装配的选择范围。
- @Autowired是Spring特有的注解,可以替换为Java注解中的@Injection。
1.3 配置Spring,使其寻找带有@Component注解的类,并为其创建bean。
- 通过Java代码中使用@ComponentScan注解,启动组件扫描
- 默认用配置类所在的包作为基础包(base package)来扫描组件
- 用value属性来指定不同的基础包:
@ComponentScan("soundsystem")
- 通过basePackages属性更加清晰地指明基础包:
@Component(basePackages="soundsystem")
- 将basePackages属性设置为一个数组来设置多个基础包:
@Component(basePackages={"soundsystem", "video"})
- 可以指定为包中所含的类或者接口:
@Component(basePackagesClasses=CDPlayer.class. DVDPlayer.class)
package com.junzerg.player_autoconfig.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.junzerg.player_autoconfig")
public class CDPlayerConfig {
}
- 在XML配置方法中,<context:component-scan>元素可以有对应的属性和子元素。
<?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">
<context:component-scan base-package="com.junzerg.player_autoconfig" />
</beans>
1.4 测试
- 测试通过Java配置的
package com.junzerg.player_autoconfig;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
//import org.junit.contrib.java.lang.system.StandardOutputStreamLog;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.junzerg.player_autoconfig.config.CDPlayerConfig;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {
@Rule
public final SystemOutRule log = new SystemOutRule().enableLog();
@Autowired
private MediaPlayer player;
@Autowired
private CompactDisc cd;
@Test
public void cdShouldNotBeNull() {
assertNotNull(cd);
}
@Test
public void play() {
player.play();
assertEquals("Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles\n", log.getLog());
}
}
- 测试通过XML配置的
package com.junzerg.player_autoconfig;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:META-INF/spring/soundsystem.xml")
public class CDPlayerXMLConfigTest {
@Rule
public final SystemOutRule log = new SystemOutRule().enableLog();
@Autowired
private MediaPlayer player;
@Autowired
private CompactDisc cd;
@Test
public void cdShouldNotBeNull() {
assertNotNull(cd);
}
@Test
public void play() {
player.play();
assertEquals("Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles\n", log.getLog());
}
}
- 测试结果
Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles
2. 通过Java代码配置bean
- 和xml相比,JavaConfig是更好的方案
- JavaConfig是配置代码,不应该包含任何的业务逻辑,也不应该侵入到业务代码中
- 通常会把JavaConfig放到单独的包中,使它与其他的业务逻辑分开
2.1 创建配置类
通过@Configuration租借表明类是配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。
注意和上一节相比,移除了@ComponentScan注解。
package com.junzerg.player_javaconfig.config;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CDPlayerConfig {
}
2.2 声明简单的bean
在JavaConfig中编写方法,创建所需类型的实例,为方法添加@Bean注解。将会把方法返回的对象注册为Spring应用上下文中的bean。
如下代码声明了CompactDisc bean:
@Bean
public CompactDisc sgtPeppers() {
return new SgtPeppers();
}
@Bean表示这个方法将返回一个要注册为Spring应用上下文的bean。方法体中是产生这个bean实例的逻辑。
默认情况下 ,bean的ID和@Bean注解的方法名相同。如下代码可以指定一个不同的名字:
@Bean(name="theSgtPeppers"
public CompactDisc sgtPeppers(){
return new SgtPeppers();
}
在Java描述中,可以发挥Java的所有功能,只要最终产生的是一个CompactDisc实例。如下代码可以随机选择一个CompactDisc播放:
@Bean
public CompactDisc randomBeatlesCD() {
int choice = (int) Math.floor(Math.random() * 4);
if(choice == 0) {
return new SgtPeppers();
}
else if(choice == 1) {
return new WhiteAlbum();
}
else if(choice == 2) {
return new HardDaysNight();
}
else {
return new Revolver();
}
}
2.3 用JavaConfig实现注入
在JavaConfig中装配bean的最简单的方式就是引用创建bean的方法。如下方法声明一个CDPlayer
@Bean
public CDPlayer cdPlayer() {
return new CDPlayer(sgtPeppers());
}
在使用了@Bean注解后,表明这个方法创建一个ID为cdPlayer的bean实例并注册到Spring应用上下文中。
但是cdPlayer()方法和前文sgtPepper()方法区别在于没有使用默认的构造器实例,而是需要传入CompactDisc对象的构造器来创建CDPlayer实例。添加@Bean之后,Spring会拦截所有对它的调用,并确保该方法所创建的bean,而不是每次都对其进行直接的调用。
例如如下代码会得到相同的SgtPepper实例:
@Bean
public CDPlayer cdPlayer(){
return new CDPlayer(sgtPepper());
}
@Bean
public CDPlayer anotherCDPlayer(){
return new CDPlayer(sgtPepper());
}
通过如下方法是引用其他bean的最佳选择:
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
return new CDPlayer(compactDisc);
}
在Sring调用cdPlayer()创建CDPlayer bean 的时候,它会自动装配一个CompactDisc到装配方法中,然后方法体可以按照合适的方法来使用它。它可以通过组件扫描功能或XML来配置,只要功能健全,不管CompactDisc用什么方式创建的,Spring都会将其传入到配置方法中,来创建CDPlayer bean。
因此注意:带有@Bean注解的方法可以采用任何必要的Java功能来产生bean实例。
2.4 测试
- 装配文件为:
package com.junzerg.javaconfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CDPlayerConfig {
@Bean
public CompactDisc compactDisc() {
return new SgtPeppers();
}
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {
return new CDPlayer(compactDisc);
}
}
- SgtPeppers.java
package com.junzerg.javaconfig;
public class SgtPeppers implements CompactDisc {
private String title = "Sgt. Pepper's Lonely Hearts Club Band";
private String artist = "The Beatles";
public void play() {
System.out.println("Playing " + title + " by " + artist);
}
}
- 测试类
package com.junzerg.javaconfig;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {
@Rule
public final SystemOutRule log = new SystemOutRule().enableLog();
@Autowired
private MediaPlayer player;
@Test
public void play() {
player.play();
assertEquals("Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles\n", log.getLog());
}
}
- 测试结果
Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles
3. 通过XML装配
3.1 创建XML配置规范
类似于使用JavaConfig要创建一个嗲有@Configuration注解的类,在XML配置中,要创建一个以<beans>元素为根的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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- configuration details go here -->
</beans>
3.2 声明简单的<bean>
类似于JavaConfig中的@Bean注解,在XML配置模式中要使用<bean>元素声明一个bean。如下代码声明了一个CompactDisc bean:
<bean class="com.junzerg. xmlconfig.SgtPeppers" />
创建这个bean的类通过class属性来指定,并且要使用全限定类名。
如果没有明确指定ID,bean会根据全限定类名来进行命名,上面代码中的bean的ID将会是"com.junzerg.xmlconfig.SgtPeppers#0"。#0用来区分相同类型的其他bean,如果声明另外一个没有明确标识的SgtPeppers,其ID将会是"com.junzerg.xmlconfig.SgtPeppoers#1"。
如下代码为bean指定ID:
<bean id="compactDisc" class="com.junzerg. xmlconfig.SgtPeppers" />
通过xml配置bean的一些特征:
- 不需要直接负责创建SgtPeppers,Spring发现的<bean>元素会调用默认构造器。
- bean类型是以字符串的形式设置在class属性中的。
- 该值的正确性需要保证
- 重命名类之后字符串需要修改
3.3 借助构造器注入初始化的bean
在XML中声明DI时,有两种配置方案可以选择:
- <constructor-arg>元素,会显得XML更冗长,但是能完成一些c-命名空间不能完成的工作。
- c-命名空间,简洁一些,但是功能有限
3.3.1 通过构造器注入bean引用
如下代码用元素的方式声明CDPlayer并通过ID引用StgPeppers:
<bean id="cdPlayer" class="com.junerg.xmlconfig.CDPlayer">
<constructor-arg ref="compactDisc" />
</bean>
如下代码用命名空间的方式声明:
- 在XML顶部声明其模式
- 在<bean>标签中使用属性
<?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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="cdPlayer" class="com.junzerg.xmlconfig.CDPlayer" c:cd-ref="compactDisc" />
</beans>
c-命名空间的属性名组成含义为:
还可以在使用参数在整个参数列表中的位置信息:
<bean id="cdPlayer" class="com.junzerg.xmlconfig.CDPlayer" c:_0-ref="compactDisc">
如果只有一个构造器参数,还可以不用标示参数:
<bean id="cdPlayer" class="com.juznerg.xmlconfig.CDPlayer" c:_-ref="compactDisc">
3.3.2 将字面量注入到构造器中
可以用一个字面量值来配置对象。
例如如下所示的CompactDisc的实现:
package com.junzerg.xmlconfig;
public class BlankDisc implements CompactDisc {
private String title;
private String artist;
public BlankDisc(String title, String artist) {
this.title = title;
this.artist = artist;
}
public void play() {
System.out.println("Playing " + title + " by " + artist);
}
}
这时需要同时修改xml配置:
- 如果使用<constructor-arg>元素,使用value属性表明给定值用字面量的形式注入到构造器中:
<bean id="compactDisc" class="com.junzerg.xmlconfig.BlankDisc">
<constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" />
<constructor-arg value="The Beatles" />
</bean>
- 如果使用c-命名空间:
- 引用构造器参数的名字,去掉-ref后缀。
<bean id="compactDisc"
class="com.junzerg.xmlconfig.BlankDisc"
c:_title="Sgt. Pepper's Lonely Hearts Club Band"
c:_artist="The Beatles" />
- 使用参数索引
<bean id="compactDisc"
class="com.junzerg.xmlconfig.BlankDisc"
c:_0="Sgt. Pepper's Lonely Hearts Club Band"
c:_1="The Beatles" />
- 如果只有一个构造器参数,可以使用如下方式:
<bean id="compactDisc"
class="com.junzerg.xmlconfig.BlankDisc"
c:_="Sgt. Pepper's Lonely Hearts Club Band" />
3.3.3 装配集合
如果构造器参数中有列表或者集合, 也需要装配进去,例如如下实现:
package com.junzerg.xmlconfig.collections;
import java.util.List;
import com.junzerg.xmlconfig.CompactDisc;
public class BlankDisc implements CompactDisc {
private String title;
private String artist;
private List<String> tracks;
public BlankDisc(String title, String artist, List<String> tracks) {
this.title = title;
this.artist = artist;
this.tracks = tracks;
}
public void play() {
System.out.println("Playing " + title + " by " + artist);
for (String track : tracks) {
System.out.println("-Track: " + track);
}
}
}
为了提供列表作为构造器参数,有以下方法:
- 最简单的方式就是使用null作为列表参数,注意需要使用<null />元素
<bean id="compactDisc" class="com.junzerg.xmlconfig.BlankDisc">
<constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" />
<constructor-arg value="The Beatles" />
<constructor-arg><null /></constructor-arg>
</bean>
- 更好的方法是提供列表或集合参数
- 使用<list>元素作为<constructor-arg>的子元素,<value>元素来制定列表列表中的每个元素:
<bean id="compactDisc" class="com.junzerg.mixedconfig.BlankDisc"
<constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" />
<constructor-arg value="The Beatles" />
<constructor-arg>
<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>
<!-- ...other tracks omitted for brevity... -->
</list>
</constructor-arg>
</bean>
- 使用ref元素代替<value>实现。
<bean id="compactDisc" class="com.junzerg.mixedconfig.Discography"
<constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" />
<constructor-arg value="The Beatles" />
<constructor-arg>
<list>
<ref bean="stgPeppers" />
<ref bean="whiteAlbum" />
<ref bean="hardDaysNight" />
<ref bean="revolver" />
</list>
</constructor-arg>
</bean>
- <set>元素同样能被用来设置集合元素
<bean id="compactDisc" class="com.junzerg.mixedconfig.BlankDisc"
<constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" />
<constructor-arg value="The Beatles" />
<constructor-arg>
<set>
<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>
<!-- ...other tracks omitted for brevity... -->
</set>
</constructor-arg>
</bean>
注意:
- 使用Set元素的话,所有重复的值都会被忽略,存放顺序也不会保证。
- c-命名空间不能 实现装配集合的功能。
3.3.4 设置属性
对于属性注入的如下类:
package com.junzerg.xmlconfig;
import org.springframework.beans.factory.annotation.Autowired;
public class CDPlayer implements MediaPlayer {
private CompactDisc cd;
@Autowired
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
public void play() {
cd.play();
}
}
p.s:对强依赖使用构造器注入,对于可选依赖使用属性注入。
接下来对CDPlayer声明为Spring bean(需要property元素应用bean并通过setCompactDisc()方法注入到compactDisc属性中):
<bean id="cdPlayer" class="com.junzerg.xmlconfig.CDPlayer">
<property name="compactDisc" ref="compactDisc" / >
</bean>
同<constructor-arg>元素可以用c-命名空间作为替代方案一样,property元素可以用p-命名空间作为替代方案:
- 在XML文件中对命名空间进行声明
- 使用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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/bean
http://www.springframework.org/schema/beans/spring-beans.xsd>
<bean id="cdPlayer" class="com.junzerg.xmlconfig.properties.CDPlayer"
p:compactDisc-ref="compactDisc" />
</beans>
- 属性名称用p:前缀,表明所设置的是一个属性
- 要注入的属性
- 属性名以-ref结尾,提示Spring要装配的是引用,而不是字面量
将字面量注入属性中
属性也可以注入字面量。例如如下Blank Disc类,不要求装配任何属性:
package com.junzerg.xmlconfig;
import java.util.List;
public class BlankDisc implements CompactDisc {
private String title;
private String artist;
private List<String> 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() {
System.out.println("Playing " + title + " by " + artist);
for( String track : tracks) {
System.out.println("-Track: " + track);
}
}
}
然后再借助<property>元素的value属性来进行属性装配:
<bean id="compactDisc" class="com.junzerg.xmlconfig.properties.BlankDisc">
<property name="title" value="Sgt. Pepper's Lonely Hearts Club Band" />
<property name="artist" value="The Beatles" />
<property name="tracks">
<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>
<value>She's Leaving Home</value>
<value>Being for the Benefit of Mr. Kite!</value>
<value>Within You Without You</value>
<value>When I'm Sixty-Four</value>
<value>Lovely Rita</value>
<value>Good Morning Good Morning</value>
<value>Sgt. Pepper's Lonely Hearts Club Band Reprise)</value>
<value>A Day in the Life</value>
</list>
</property>
</bean>
同样,也可以通过p-命名空间的属性来讲字面量注入,和c-命名空间一样的是,装备bean应用与装配字面量的唯一区别在于是否带有"-ref"后缀:
<bean id="compactDisc" class="com.junzerg.xmlconfig.properties.BlankDisc"
p:title="Sgt. Pepper's Lonely Hearts Club Band"
p:artist="The Beatles">
<property name="tracks">
<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>
<value>She's Leaving Home</value>
<value>Being for the Benefit of Mr. Kite!</value>
<value>Within You Without You</value>
<value>When I'm Sixty-Four</value>
<value>Lovely Rita</value>
<value>Good Morning Good Morning</value>
<value>Sgt. Pepper's Lonely Hearts Club Band (Reprise)</value>
<value>A Day in the Life</value>
</list>
</property>
</bean>
注意,不能使用p-命名空间来装配集合,没有便利方式使用p-命名空间来指定一个值(或者bean应用)的列表。但是可以使用-util-命名空间的一些功能来简化bean:
- 先在XML中声明util-命名空间及其模式:
<?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: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/util
http://www.springframework.org/schema/util/spring-util.xsd">
...
</bean>
- 使用<util:list>元素,创建一个立标bean:
<util:list id="trackList">
<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>
<value>She's Leaving Home</value>
<value>Being for the Benefit of Mr. Kite!</value>
<value>Within You Without You</value>
<value>When I'm Sixty-Four</value>
<value>Lovely Rita</value>
<value>Good Morning Good Morning</value>
<value>Sgt. Pepper's Lonely Hearts Club Band (Reprise)</value>
<value>A Day in the Life</value>
</util:list>
- 再将bean注入到需要引入的bean的tracks属性中:
<bean id="compactDisc" class="com.junzerg.xmlconfig.properties.BlankDisc"
p:title="Sgt. Pepper's Lonely Hearts Club Band"
p:artist="The Beatles"
p:tracks-ref="trackList" />
p.s.:还有可用的util-命名空间的成员如下:
元素 | 描述 |
---|---|
<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,其中包含值或者引用 |
4 导入和混合配置
4.1 在JavaConfig中引入XML配置
在JavaConfig中可以使用@import注解导入其他的JavaConfig,例如:
package com.junzerg.mixedconfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Bean;
@Configuration
@Import(CDPlayerConfig.class)
public class SoundSystemConfig {
@Bean
public CDPlayer cdPlayer(CompactDisc cd){
return new CDPlayer(cd);
}
}
对于XML配置的BlankDisc:
cd-config.xml
<bean id="compactDisc" class="com.junzerg.mixedconfig.BlankDisc"
c:_0="Sgt. Pepper's Lonely Hearts Club Band"
c:_1="The Beatles">
<constructor-arg>
<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>
<!-- ...other tracks omitted for brevity... -->
</list>
</constructor-arg>
</bean>
以及JavaConfig注解的CDPlayerConfig
那么可以用@ImportResource注解,将他们引入同一个JavaConfig:
package com.junzerg.mixedconfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
@Configuration
@Import(CDPlayerConfig.class)
@ImportResource("classpath:cd-config.xml")
public class SoundSystemConfig {
}
4.2 在XML配置中引用JavaConfig
可以用<import>元素在XML中引入另外的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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<impport resource="cd-config.xml" />
<bean id="cdPlayer"
class="com.junzerg.mixedconfig.CDPlayer"
c:cd-ref="compactDisc" />
</beans>
要将JavaConfig文件引入xml文件,可以直接使用<bean>元素:
<?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 class="com.junzerg.mixedconfig.CDConfig" />
<bean id="cdPlayer"
class="com.junzerg.mixedconfig.CDPlayer"
c:cd-ref="compactDisc" />
</beans>
5. 其他
5.1 本节使用了Spring的测试功能,因此要在Maven中添加Spring-test依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.10.RELEASE</version>
<scope>test</scope>
</dependency>
5.2 本节原例中的org.junit.contrib.java.lang.system.StandardOutputStreamLog需要在Maven中引入以下依赖
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>
<version>1.16.1</version>
<scope>test</scope>
</dependency>
另:原例中使用的StandardOutputStreamLog 包在最新的Junit中已经没有了,根据网上修改成以下,并修改相关用法:
import org.junit.contrib.java.lang.system.SystemOutRule;
@Rule
public final SystemOutRule log = new SystemOutRule().enableLog();