Spring 导入和混合配置

64 阅读2分钟

在 Spring 中多种配置方案不是互斥的,可以混合使用。在混合配置时,自动配置并不在意要装配的 bean 来自哪里,它会考虑到 Spring 容器中的所有 bean,不管它是通过配置类、XML 配置文件或者组件扫描获取到的。

在配置类中引用 XML 配置

首先,分别创建 CompactDisc 接口及其实现类 SgtPeppers,Media 接口及其实现类 CDPlayer,BlankDisc,代码如下:

package org.example.mixconfig;

public interface CompactDisc {
    void play();
}
package org.example.mixconfig;

public class SgtPeppers implements CompactDisc{
    private String title = "Sgt. Pepper's Lonely Hearts Club Band";
    private String artist = "The Beatles";

    @Override
    public void play() {
        System.out.println("Playing " + title + " by " + artist);
    }
}
package org.example.mixconfig;

public interface MediaPlayer {
    void play();
}
package org.example.mixconfig;

public class CDPlayer implements MediaPlayer{

    private CompactDisc cd;

    public CDPlayer(CompactDisc cd){
        this.cd = cd;
    }
    @Override
    public void play() {
        cd.play();
    }
}

然后,定义一个 CDConfig 类,代码如下:

package org.example.mixconfig;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CDConfig {
    @Bean
    public CompactDisc compactDisc(){
        return new SgtPeppers();
    }
}

接着,创建一个 CDPlayerConfig 类,并使用 @Import 注解引入 CDConfig 类,代码如下:

package org.example.mixconfig;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(CDConfig.class) // 导入外部配置类
public class CDPlayerConfig {
    @Bean
    public CDPlayer cdPlayer(CompactDisc compactDisc){
        return new CDPlayer(compactDisc);
    }
}

另外一种方式是不在 CDPlayerConfig 类中引入 CDConfig 类,而是使用 @Import 注解将这两个配置类组合到一个更高级别的配置类中,代码如下:

package org.example.mixconfig;

import org.springframework.context.annotation.Import;
import org.springframework.test.context.ContextConfiguration;

@ContextConfiguration
@Import({CDPlayerConfig.class, CDConfig.class}) // 导入外部配置类
public class SoundSystemConfig {
}

注意,这里因为 CDPlayerConfig 类、 CDConfig 类、SoundSystemConfig 类都在一个包中,所以省略了包路径,如果不在一个包中可以使用类的全限定路径。

如果我们通过 XML 来配置了 SgtPeppers 类时,配置文件名为 cd-config.xml,位于项目的类路径(resources 目录)下。配置如下:

<!--cd-config.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="compactDisc" class="org.example.mixconfig.SgtPeppers"/>

</beans>

可以使用 @ImportResource 注解在配置类中引入 XML 配文件中的配置:

package org.example.mixconfig;

import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.test.context.ContextConfiguration;

@ContextConfiguration
@Import(CDPlayerConfig.class) // 导入外部的配置类
@ImportResource("classpath:cd-config.xml") //导入外部的 XML 配置文件
public class SoundSystemConfig {
}
在 XML 配置中引用配置类

在 XML 配置文件中,我们可以使用 <import> 元素来拆分 XML 配置。例如,在cdplayer-config.xml 配置文件中导入cd-config.xml配置文件,代码如下:

<!--cdplayer-config.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">
    <!--导入外部的 XML 配置文件-->
    <import resource="classpath:cd-config.xml"/>
    <bean id="cdPlayer" class="org.example.mixconfig.CDPlayer">
        <constructor-arg ref="compactDisc"/>
    </bean>
</beans>

另外,还可以在 XML 配置中导入外部的配置类,例如,将前面的 CDConfig 配置类导入到cdplayer-config.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">
    
    <!--在 XML 中导入外部的配置类-->
    <bean class="org.example.mixconfig.CDConfig"/>
    <bean id="cdPlayer" class="org.example.mixconfig.CDPlayer">
        <constructor-arg ref="compactDisc"/>
    </bean>
</beans>

配置类和 XML 配置文件可以组合起来使用。不管使用配置类还是 XML 配置文件,通常都会创建一个根配置,这个配置将两个或者多个配置类/XML配置文件组合起来,在根配置中开启组件扫描(通过<context:component-scan> 或 @ComponentScan)。