本系列博客为spring In Action 这本书的学习笔记
前言
之前在Spring学习笔记(三) — 装配Bean之通过Java代码装配Bean的最后提到:
在这里, Spring会自动给cdPlayer()方法匹配一个CompactDisc类型的Bean, 甚至这个Bean可以不在这个JavaConfig中, 它可以通过组件扫描或者通过XML进行配置来被这里的cdPlayer()方法使用.
说实话, 当时我不是很明白这段话的意思, 因为书中提到JavaConfig中被装配的Bean可以不必要是在本JavaConfig文件中声明的, 它可以来自其它的JavaConfig, 甚至都可以来自其它的XML配置文件, 于是我就去试验了一下, 我在XML中声明了一个CompactDisc Bean, 希望被本JavaConfig中的CDplayer Bean自动装配, 然而并没有成功, IDEA还是报错:没有找到匹配的Bean. 如果你也曾有这样的疑惑, 那么你就能在这篇博客里找到答案.
混合配置, 顾名思义, 就是将两种装配方式混合使用. 我们可以在JavaConfig中引入XML配置, 也可以在XML配置中引用JavaConfig. 而前面提到的我之前遇到的问题, 就是因为我没有在JavaConfig中正确地引用XML配置. 那么下面来看看具体如何操作吧.
1. 在JavaConfig中导入配置
(1) 在JavaConfig中引入另一个 JavaConfig
之前我们在JavaConfig配置中写过一个CDPlayerConfig, 贴出它的代码来看一下:
程序1: CDPlayerConfig
@Configuration
public class CDPlayerConfig {
@Bean
public CompactDisc jay(){
return new Jay();
}
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
return new CDPlayer(compactDisc);
}
}
在上面地代码中, 我们将CompactDisc Bean和CDPlayer Bean装配在了一个JavaConfig中, 现在, 我们觉得应该将CompactDisc类型的Bean和CDPlayer类型的Bean应该分开配置, 所以要将CompactDisc Bean从CDPlayerConfig中拎出来. 像下面这样:
程序2: CDConfig
@Configuration
public class CDConfig {
@Bean
public CompactDisc compactDisc(){
return new Jay();
}
}
此时要将这两个Bean装配在一起, 我们可以在CDPlayerConfig中使用@Import标注将CDConfig导入. 如下:
程序3: CDPlayerConfig
@Configuration
@Import(CDConfig.class)
public class CDPlayerConfig {
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
return new CDPlayer(compactDisc);
}
}
或者如果不想在CDPlayerConfig中使用@Import标注, 我们可以再重新创建一个Config, 将这两个Config都导入, 如下:
程序4: SoundSystemConfig
@Configuration
@Import({CDPlayerConfig.class, CDConfig.class})
public class SoundSystemConfig {
}
不知道你们有没有发现问题! 如果再CDPlayerConfig中去掉了@Import标注, 那么cdPlayer这个方法就会报错, 这是因为它强依赖于一个CompactDisc Bean, 当我们去掉了@Import标注之后, 再CDPLayerConfig中就找不到一个CompactDisc的Bean, 这样在CDPlayerConfig中就会报错.
然而! 这里报错, 并不会影响最终程序的运行!!! 运行结果仍是正确的, 注入也是成功了的, 所以不必理会这里的报错.
(2) 在JavaConfig中导入XML配置
程序5: 一个简单的XML配置文件CDMix.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="jay" class="com.SoundSystem_Mix.Jay" />
</beans>
程序6: 导入CDMix.xml和CDPlayerConfig的SoundSystemConfig
@Configuration
@Import(CDPlayerConfig.class)
@ImportResource("classpath:CDMix.xml")
public class SoundSystemConfig {
}
而我前面遇到的那个问题是因为我没有将那个XML文件使用@Import标注导入进来, 所以Spring提示无法找到那个Beam.
2. 在XML中导入配置
我们在JavaConfig中引用另外一个JavaConfig或者XML文件, 使用的是@Import标注, 那么在XML配置文件, 引用另外一个XML配置文件或JavaConfig需要用到<import>元素.
先来看一下如何让在XML配置文件中引用另一个XML配置文件.
(1) 在XML配置文件中引用XML文件
程序7: 在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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="CDMix.xml" />
<bean id="cdPlayer" class="com.SoundSystem_Mix.CDPlayer" />
</beans>
(2) 在XML配置文件中引用JavaConfig
在XML配置文件中引用JavaConfig与在XML中引用XML还略微有一点不同.
在XML中引用JavaConfig要将引入的JavaConfig声明为一个Bean, 代码如下:
程序8: 在XML中引用JavaConfig
<?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 class="com.SoundSystem_Mix.CDConfig" />
<bean id="cdPlayer" class="com.SoundSystem_Mix.CDPlayer" />
</beans>