三种方案:
在xml中进行显式配置
在java中进行显式配置
隐式的bean发现机制和自动装配
自动装配bean
自动装配的角度
组件扫描(component scanning) :Spring会自动发现应用上下文中所创建的bean。
自动装配(autowiring) :Spring自动满足bean之间的依赖
//这个注解表明该类会作为组件类,并告知spring要为这个类创建bean
@Component
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);
}
}
@Component注解表明该类会作为组件类,并告知spring要为这个类创建bean,此组件默认不启用
@Configuration
//这个注解会在spring中启用组件扫描,默认会扫描这个包及这个包下面的子包中的@Component
@ComponentScan
public class CDPlayerConfig {
}
@ComponentScan启用了组件扫描,默认会扫描这个包及这个包下面的子包中的@Component
基于xml的配置
<context:component-scan base-package="soundsystem" />
功能如上
@RunWith(SpringJUnit4ClassRunner.class)//自动创建spring的应用上下文
@ContextConfiguration(classes=CDPlayerConfig.class)//在CDPlayerConfig中配置,因为其中包含了@ComponentScan,所以最终的应用上下文包含CompactDisc bean
public class CDPlayerTest {
@Rule
public final StandardOutputStreamLog log = new StandardOutputStreamLog();
@Autowired
private MediaPlayer player;
@Autowired
private CompactDisc cd;
@Test
public void cdShouldNotBeNull() {
//判断CompactDisc bean是否在应用上下文中
assertNotNull(cd);
}
@Test
public void play() {
player.play();
assertEquals(
"Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles\n",
log.getLog());
}
}
会默认给bean设置名称,这个bean所给的ID为把类名的第一个字母小写
手动设置ID
法一:
@Component("loney")
public class SgtPeppers implements CompactDisc {
}
法二:
使用java依赖注入规范中的@Named注解来为bean设置ID@Named可以作为@Component的替代
import javax.inject.Named;
@Named("loney")
public class SgtPeppers implements CompactDisc {
}
设置组件扫描
指定不同包
@Configuration
@ComponentScan("soundsystem")
public class CDPlayerConfig {
}
1、明确指明扫描的包
@Configuration
@ComponentScan(basePackages="soundsystem")
public class CDPlayerConfig {
}
扫描复数包
@Configuration
@ComponentScan(basePackages={"soundsystem","video"})
public class CDPlayerConfig {
}
String形式的基础包不安全,重构可能出现错误
2、指定包中所包含的类或接口
类所在的包将作为基础包
@Configuration
@ComponentScan(basePackageClasses={CDPlayer.class,MediaPlayer.class})
public class CDPlayerConfig {
}
可以定义个空标记接口作为组件类,避免使用使用实际应用代码
对象之间没有依赖,组件扫描就够了,对象之间依赖的话需要将组件扫描得到的bean和他们的依赖装配到一起
为bean添加注解实现自动装配
自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean
自动实例化,把CompactDisc加载进来
@Component
public class CDPlayer implements MediaPlayer {
private CompactDisc cd;
@Autowired
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
public void play() {
cd.play();
}
}
@Autowired不仅可以注释在构造器上,还能注释在setter上
@Autowired
public void setCompactDisc(CompactDisc cd){
this.cd = cd;
}
不管是构造器、
Setter
方法还是其他的方法,
Spring
都会尝试满足方法参数上所声明的依赖。 假如有且只有一个
bean
匹配依赖需求的话, 那么这个
bean
将会被装配进来。如果没有匹配的
bean
, 那么在应用上下文创建的时候,
Spring
会抛出一个异常。 为了避免异常的出现, 你可以将
@Autowired
的
required
属性设置为
false
:
@Autowired(required=false)
public void setCompactDisc(CompactDisc cd){
this.cd = cd;
}
将
required
属性设置为
false
时,
Spring
会尝试执行自动装配, 但是如果没有匹配的
bean
的话,
Spring
将会让这个
bean
处于未装配的状态。 但是, 把
required
属性设置为
false
时, 你需要谨慎对待。 如果在你的代码中没有进行
null
检查的话, 这个处于未装配状态的属性有可能会出现
NullPointerException
。
如果有多个bean都能满足依赖关系的话,Spring将会抛出一个异常,表明没有明确指定要选择哪个bean进行自动装配。
@Inject和@autowired类似
@Inject
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
@RunWith(SpringJUnit4ClassRunner.class)//自动创建spring的应用上下文
@ContextConfiguration(classes=CDPlayerConfig.class)//在CDPlayerConfig中配置,因为其中包含了@ComponentScan,所以最终的应用上下文包含CompactDisc bean
public class CDPlayerTest {
@Rule
//源于System Rules库的一个Junit规则,能够基于控制台输出编写断言,断言play方法输出被发送到控制台上
public final StandardOutputStreamLog log = new StandardOutputStreamLog();
@Autowired
private MediaPlayer player;
@Autowired
private CompactDisc cd;
@Test
public void cdShouldNotBeNull() {
//判断CompactDisc bean是否在应用上下文中
assertNotNull(cd);
}
@Test
public void play() {
player.play();
assertEquals(
"Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles\n",
log.getLog());
}
}
通过java代码装配bean
创建配置类
@Configuration
public class CDPlayerConfig {
}
创建
JavaConfig
类的关键在于为其添加
@Configuration
注解,
@Configuration
注解表明这个类是一个配置类, 该类应该包含在
Spring
应用上下文中如何创建
bean
的细节。
声明简单的bean
@Configuration
public class CDPlayerConfig {
@Bean
public CompactDisc sgtPeppers(){
return new SgtPeppers();
}
}
@Bean
注解会告诉
Spring
这个方法将会返回一个对象, 该对象要注册为
Spring
应用上下文中的
bean
。 方法体中包含了最终产生
bean
实例的逻辑
默认情况下, bean的ID与带有@Bean注解的方法名是一样的。 在本例中,bean的名字将会是sgtPeppers。
也可以重命名@Bean(name="lonehy")
借助JavaConfig实现注入设置依赖关系,CDPlayer bean依赖于CompactDisc,可以引用创建bean的方法
@Configuration
public class CDPlayerConfig {
@Bean(name="lonehy")
public CompactDisc sgtPeppers(){
return new SgtPeppers();
}
@Bean
public CDPlayer cdPlayer(){
return new CDPlayer(sgtPeppers());
}
}
@Bean注解,Spring会拦截所有对它的调用,确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用,保证单例,返回的是spring创建的bean
下面的更好理解
此时CompactDisc可以通过组件扫描或者XML配置
构造器方式注入
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
return new CDPlayer(compactDisc);
}
在这里,
cdPlayer()
方法请求一个
CompactDisc
作为参数。 当
Spring
调用
cdPlayer()
创建
CDPlayer
bean
的时候, 它会自动装配一个
CompactDisc
到配置方法之中。 然后, 方法体就可以按照合适的方式来使用它。 借助这种技术,
cdPlayer()
方法也能够将
CompactDisc
注入到
CDPlayer
的构造器中, 而且不用明确引用
CompactDisc
的
@Bean
方法。
Setter注入
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
//return new CDPlayer(compactDisc);
CDPlayer cdPlayer = new CDPlayer(compactDisc);
cdPlayer.setCompactDisc(compactDisc);
return cdPlayer;
}
带有
@Bean
注解的方法可以采用任何必要的
Java
功能来产生
bean
实例
通过XML装配bean
创建XML配置规范 在使用 JavaConfig 的时候, 这意味着要创建一个带有 @Configuration 注解的类, 而在 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"
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">
<!--configuration details go here-->
</beans>
在
JavaConfig
中所需要的只是
@Configuration
, 但在使用
XML
时, 需要在配置文件的顶部声明多个
XML
模式(
XSD
) 文件, 这些文件定义了配置
Spring
的
XML
元素。借助
Spring Tool Suite
创建
XML
配置文件创建和管理
Spring XML
配置文件的一种简便方式是使用
Spring Tool Suite
(
https://spring.io/tools/sts
) 。 在
Spring Tool Suite
的菜单中,选择 File>New>Spring Bean Configuration File , 能够创建 SpringXML 配置文件, 并且可以选择可用的配置命名空间。 用来装配 bean 的最基本的 XML 元素包含在 spring-beans 模式之中, 在上面这个 XML 文件中, 它被定义为根命名空间。 <beans> 是该模式中的一个元素, 它是所有 Spring 配置文件的根元素。
声明一个简单的bean
<bean> 元素类似于 JavaConfig 中的 @Bean 注解 这里声明了一个很简单的 bean , 创建这个 bean 的类通过 class 属性来指定的, 并且要使用全限定的类名。
因为没有明确给定 ID , 所以这个 bean 将会根据全限定类名来进行命名。 在本例中, bean 的 ID 将会是 “ soundsystem.SgtPeppers#0 ” 。 其中, “ #0 ” 是一个计数的形式, 用来区分相同类型的其他 bean 。 如果你声明了另外一个 SgtPeppers , 并且没有明确进行标识, 那么它自动得到的 ID 将会是 “ soundsystem.SgtPeppers#1 ” 。
<?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 class="soundsystem.Sgtpeppers">
</beans>
设置id
<bean id="compactDisc" class="soundsystem.Sgtpeppers">
当
Spring
发现这个
<bean>
元素时, 它将会调用
SgtPeppers
的默认构造器来创建
bean
。 在
XML
配置中,
bean
的创建显得更加被动
将 bean 的类型以字符串的形式设置在了 class 属性中 ,可能会出错,但不会检测出来
构造器注入初始化bean
在Spring XML配置中, 只有一种声明bean的方式: 使用<bean>元素并指定class属性。Spring会从这里获取必要的信息来创建bean。
声明DI有多种方式,构造器注入有俩种基本的配置方案
<constructor-arg>元素
使用Spring 3.0所引入的c-命名空间
两者的区别在很大程度就是是否冗长烦琐。 <constructor-arg>元素比使用c-命名空间会更加冗长, 从而导致XML更加难以读懂。 另外, 有些事情<constructor-arg>可以做到, 但是使用c-命名空间却无法实现。
法一:
如下,CDPlayer bean有一个接受CompactDisc类型的构造器。 现在已经声明了SgtPeppersbean, 并且SgtPeppers类实现了CompactDisc接口, 所以实际上我们已经有了一个可以注入到CDPlayer bean中的bean。在XML中声明CDPlayer并通过ID引用SgtPeppers,当Spring遇到这个<bean>元素时, 它会创建一个CDPlayer实例。<constructor-arg>元素会告知Spring要将一个ID为compactDisc的bean引用传递到CDPlayer的构造器中。
<?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="compactDisc" class="soundsystem.Sgtpeppers">
<bean id="cdPlayer" class="soundsystem.CDPlayer">
<constructor-arg ref="compactDisc">
</bean>
</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"
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>
<bean id="compactDisc" class="soundsystem.Sgtpeppers">
<!-- <bean id="cdPlayer" class="soundsystem.CDPlayer">
<constructor-arg ref="compactDisc">
</bean> -->
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:cd-ref="compactDisc"/>
直接引用了构造器参数的名称。 引用参数的名称看起来有些怪异, 因为这需要在编译代码的时候, 将调试标志( debug symbol ) 保存在类代码中。 如果优化构建过程, 将调试标志移除掉, 那么这种方式可能就无法正常执行了
替代方式:
<!-- <bean id="cdPlayer" class="soundsystem.CDPlayer" c:cd-ref="compactDisc"/> -->
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_0-ref="compactDisc"/>
这个
c-
命名空间属性看起来似乎比上一种方法更加怪异。 将参数的名称替换成了
“0”
, 也就是参数的索引。 因为在
XML
中不允许数字作为属性的第一个字符, 因此必须要添加一个下画线作为前缀。使用索引来识别构造器参数感觉比使用名字更好一些。 即便在构建的时候移除掉了调试标志, 参数却会依然保持相同的顺序。 如果有多个
构造器参数的话, 这当然是很有用处的。 在这里因为只有一个构造器参数, 所以我们还有另外一个方案
——
根本不用去标示参数:
<!-- <bean id="cdPlayer" class="soundsystem.CDPlayer" c:_0-ref="compactDisc"/> -->
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_-ref="compactDisc"/>
将字面量注入到构造器中
public class BlankDisc implements CompactDisc{
private String title;
private String artist;
public BlankDisc(String title, String artist) {
this.title = title;
this.artist = artist;
}
@Override
public void play() {
System.out.println(title+" "+artist);
}
}
<bean id="compactDisc" class="soundsystem.BlankDisc">
<constructor-arg value="hh">
<constructor-arg value="bb">
</bean>
使用了
value
属性, 通过该属性表明给定的值要以字面量的形式注入到构造器之中
使用c-命名
<!-- <bean id="compactDisc" class="soundsystem.BlankDisc">
<constructor-arg value="hh">
<constructor-arg value="bb">
</bean> -->
<bean id="compactDisc" class="soundsystem.BlankDisc"
c:_title ="hh" c:_artist="bb"/>
装配字面量与装配引用的区别在于属性名中去掉了
“
-ref
”
后缀
<bean id="compactDisc" class="soundsystem.BlankDisc"
c:_0 ="hh" c:_1="bb"/>
XML
不允许某个元素的多个属性具有相同的名字。 因此, 如果有两个或更多的构造器参数的话, 我们不能简单地使用下画线进行标示。 但是如果只有一个构造器参数的话, 我们就可以这样做了。不用标注参数
<bean id="compactDisc" class="soundsystem.BlankDisc"
c:_ ="hh"/>
装配集合public class BlankDisc implements CompactDisc{
private String title;
private String artist;
private List<String> tracks;
public BlankDisc(String title, String artist) {
this.title = title;
this.artist = artist;
}
public BlankDisc(String title, String artist, List<String> tracks) {
super();
this.title = title;
this.artist = artist;
this.tracks = tracks;
}
@Override
public void play() {
System.out.println(title+" "+artist);
for (String string : tracks) {
System.out.println(string);
}
}
}
有集合时,要对它进行处理
法一:将列表声明成null,因为它是构造器参数,所以必须声明
<bean id="compactDisc" class="soundsystem.BlankDisc">
<constructor-arg value="hh">
<constructor-arg value="bb">
<constructor-arg><null/></constructor-arg>
</bean>
注入期可以正常执行,调用方法时会报空指针异常
法二:提供一个名词列表
1、可以使用<list>元素将其声明为一个列表
<bean id="compactDisc" class="soundsystem.BlankDisc">
<constructor-arg value="hh">
<constructor-arg value="bb">
<constructor-arg>
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</constructor-arg>
</bean>
<list>
元素是
<constructor-arg>
的子元素, 这表明一个包含值的列表将会传递到构造器中。 其中,
<value>
元素用来指定列表中的每个元素。
2、可以使用ref
如含有此构造方法
public BlankDisc(String title, String artist, List<CompactDisc> disc) {
super();
this.title = title;
this.artist = artist;
this.disc = disc;
}
<bean id="compactDisc" class="soundsystem.BlankDisc">
<constructor-arg value="hh">
<constructor-arg value="bb">
<constructor-arg>
<list>
<ref bean="SgtPeppers">
<ref bean="WhiteAlbum">
</list>
</constructor-arg>
3.可以使用<set>元素
<bean id="compactDisc" class="soundsystem.BlankDisc">
<constructor-arg value="hh">
<constructor-arg value="bb">
<constructor-arg>
<set>
<value>1</value>
<value>2</value>
<value>3</value>
</set>
</constructor-arg>
</bean>
<set>
和
<list>
元素的区别不大, 其中最重要的不同在于当
Spring
创建要装配的集合时, 所创建的是
java.util.Set
还是
java.util.List
。 如果是
Set
的话, 所有重复的值都会被忽略掉, 存放顺序也不会得以保证。 不过无论在哪种情况下, <set> 或 <list> 都可以用来装配 List 、 Set 甚至数组
目前, 使用 c- 命名空间的属性无法实现装配集合的功能。
设置属性
作为一个通用的规则,对强依赖使用构造器注入, 而对可选性的依赖使用属性注入
public class CDPlayer implements MediaPlayer {
private CompactDisc cd;
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
public void play() {
cd.play();
}
}
此时,CDPlayer没有任何的构造器(除了隐含的默认构造器) , 它也没有任何的强依赖。 因此, 可以采用如下的方式将其声明为Spring bean
<bean id="cdPlayer" class="soundsystem.CDPlayer">
但这样会报空指针异常,因为没有注入CompactDisc
<bean id="compactDisc" class="soundsystem.Sgtpeppers">
<bean id="cdPlayer" class="soundsystem.CDPlayer">
<property name="compactDisc" ref="compactDisc">
</bean>
<property>元素为属性的Setter方法所提供的功能,与<constructor-arg>元素为构造器所提供的功能是一样的
在本例中, 它引用了ID为compactDisc的bean(通过ref属性) , 并将其注入到compactDisc属性中(通过setCompactDisc()方法)
Spring为<constructor-arg>元素提供了c-命名空间作为替代方案, 与之类似,Spring提供了更加简洁的p-命名空间,作为<property>元素的替代方案。 为了启用p-命名空间, 必须要在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: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">
可以使用如下p-命名空间
<bean id="cdPlayer" class="soundsystem.CDPlayer" p:compactDisc-ref="compactDisc"/>
将字面量注入到属性中
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);
}
}
}
<bean id="compactDisc"
class="soundsystem.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>
</list>
</property>
</bean>
除了使用
<property>
元素的
value
属性来设置
title
和
artist
, 我们还使用了内嵌的
<list>
元素来设置
tracks
属性, 这与之前通过
<constructor-arg>
装配
tracks
是完全一样的。
使用 p- 命名空间的属性来完成该功能
<bean id="compactDisc"
class="soundsystem.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>
</list>
</property>
</bean>
与
c-
命名空间一样, 装配
bean
引用与装配字面量的唯一区别在于是否带有
“-ref”
后缀。 如果没有
“-ref”
后缀的话, 所装配的就是字面量
不能使用 p- 命名空间来装配集合, 没有便利的方式使用 p- 命名空间来指定一个值(或 bean 引用) 的列表。 但是, 我们可以使用 Spring util- 命名空间中的一些功能来简
化 BlankDisc 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: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">
util-
命名空间所提供的功能之一就是
<util:list>
元素, 它会创建一个列表的
bean
<bean id="compactDisc"
class="soundsystem.properties.BlankDisc"
p:title="Sgt. Pepper's Lonely Hearts Club Band"
p:artist="The Beatles"
p:tracks-ref="trackList" />
<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>
</util:list>
<util:list>
只是
util-
命名空间中的多个元素之一
导入和混合配置
在JavaConfig中引入XML配置
@Configuration
public class CDConfig {
@Bean
public CompactDisc compactDisc() {
return new SgtPeppers();
}
}
@Configuration
public class CDPlayerConfig {
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {
return new CDPlayer(compactDisc);
}
}
将以上俩个类组合
法一:在CDPlayerConfig中使用@Import注解导入CDConfig
@Configuration
@Import(CDConfig.class)
public class CDPlayerConfig {
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {
return new CDPlayer(compactDisc);
}
}
法二:
创建一个更高级别的SoundSystemConfig, 在这个类中使用@Import将两个配置类组合在一起
@Configuration
@Import({CDPlayerConfig.class,CDConfig.class})
public class SoundSystemConfig {
}
法三,xml配置
@Configuration
@Import(CDPlayerConfig.class)
@ImportResource("classpath:cd-config.xml")
public class SoundSystemConfig {
}
<bean id="compactDisc"
class="soundsystem.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>
两个
bean——
配置在
JavaConfig
中的
CDPlayerConfig
以及配置在
XML
中
BlankDisc
——
都会被加载到
Spring
容器之中。 因为
CDPlayerConfig
中带有
@Bean
注解的方法接受一个
CompactDisc
作为参数, 因此
BlankDisc
将会装配进来, 此时与它是通过
XML
配置的没有任何关系。
@Configuration
public class CDPlayerConfig {
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {
return new CDPlayer(compactDisc);
}
}
在xml中引用JavaConfig使用 import 元素来拆分 XML 配置
<import resoune=""cd-config.xml/>
<bean id="cdPlayer"
class="soundsystem.CDPlayer"
c:cd-ref="compactDisc" />
<import>
元素只能导入其他的
XML
配置文件, 并没有
XML
元素能够导入
JavaConfig
类
<bean>可以将JavaConfig类导入XML配置中
<bean class="soundsystem.CDConfig" />
<import resoune=""cd-config.xml/>
<bean id="cdPlayer"
class="soundsystem.CDPlayer"
c:cd-ref="compactDisc" />
两种配置
——
其中一个使用
XML
描述, 另一个使用
Java
描述
——
被组合在了一起。
可以将 CDConfig bean 从之前的 XML 文件中移除掉, 而是使用第三个配置文件将这两个组合在一起
<bean class="soundsystem.CDConfig" />
<import resoune="cdplayer-config.xml"/>