装配Bean

装配Bean

装配Bean(wiring Bean)

装配bean有3种方式:

  • xml显示配置
  • java显示配置
  • 自动配置(注解方式)

自动配置(注解方式)

要使用自动配置,需要用到组件扫描自动装配
组件扫描(component scanning):扫描spring应用上下文(application context),发现要创建的bean。
自动装配(autowiring):自动满足bean的依赖关系,把一个bean所需要依赖的bean都装配到这个bean中。

组件扫描

组件扫描默认是不启动的。

启动组件扫描有2种方式:

  • 基于java的配置
  • 基于xml的配置
基于java的配置

使用注解@ComponentScan
@ComponentScan:在类的声明处使用,会扫描这类所在的包及其子包的所有类。

基于xml的配置

在spring的xml文件中加入标签<context:component-scan>
<context:component-scan base-package=“要扫描的包的全路径path”>:就会扫描path包及其子包的所有类

要让spring能自动创建我们想要创建的bean,除了要使用组件扫描,还要告诉spring哪些bean是要spring容器来创建的。

声明要创建的bean

使用注解@Component声明某个类是由spring来创建。
@Component:在需要spring创建的类的声明外使用这个注解。

自动装配

自动装配使用注解@Autowired
@Autowired:在类的内部使用,表明这个类要依赖其他的某个类。

例子
创建组件扫描类
package com.test.soundsSystem;

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

@Configuration
@ComponentScan
public class CDPlayerConfig {

}
创建bean
  • 接口
package com.test.soundsSystem;

public interface CompactDisc {
	void play();
}
  • 实现类
package com.test.soundsSystem;

import org.springframework.stereotype.Component;

@Component
public class SgtPeppers implements CompactDisc {
	
	public void play() {
		System.out.println("SgtPeppers play");
	}

}
测试
package com.test.soundsSystem;

import static org.junit.Assert.assertNotNull;

import org.junit.Test;
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 {

	@Autowired
	private CompactDisc cd;
	
	@Test
	public void test1() {
		cd.play();
		assertNotNull(cd); //运行成功,Junit窗口绿条
	}
}

运行结果:
Junit窗口绿条
console控制台输出 SgtPeppers play

为组件扫描的bean命名(id)

spring会为应用上下文(application context)管理的bean赋予一个id,id默认是首字母小写的类名。我们可以为bean重新赋予新的id,有2种方式:

  • @Component(“id”)
  • @Named(“id”)

两个注解都是在类上使用。

关于@ComponentScan设置组件扫描的基础包

@ComponentScan是扫描这个注解定义的类所在的包及其子包,但是如果有2个或以上的基础包,或者这样说,基础包里包含了不想扫描的包,那么就需要使用@ComponentScan来设置基础包。有2个属性能完成这个功能:

  • basePackages
  • basePackageClasses
basePackages属性

basePackages属性有3种使用方式:

  • @ComponentScan(“basePackagePath”)
  • @ComponentScan(basePackages=“basePackagePath”)
  • @ComponentScan(basePackages={“basePackagePath1”, “basePackagePath2”, …}):这里定义多个基础包

这里使用的是字符串类型,这种方法是类型不安全的。如果项目需要重构时,包的名称可能会改变。所以可以使用下面的basePackageClasses方式。

basePackageClasses
  • @ComponentScan(basePackageClass={AClass.class, BClass.class, …})

会把AClass和BClass类所在的包作为基础包。

自动装配

可以使用注解@Autowired进行自动装配,@Autowired可以用在4种地方:

  • 构造器
  • setter方法
  • 普通方法
  • 属性
构造器
@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;
    
    @Autowired
    public CDPlayer(CompactDisc cd) {
        this.cd = cd;
    }
}

spring启动后,在创建CDPlayer bean时,会把相应的CompactDisc bean注入。

setter方法
@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;
    
    @Autowired
    public void setCompactDisc(CompactDisc cd) {
        this.cd = cd;
    }
}
普通方法

其实普通方法和setter方法是一样的,就是方法的名称不重要,这里方法名改为insertCompactDisc。

@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;
    
    @Autowired
    public void insertCompactDisc(CompactDisc cd) {
        this.cd = cd;
    }
}
测试
  • 接口
package com.test.soundsSystem;

public interface MediaPlayer {
	void play();
}
  • 实现类
package com.test.soundsSystem;

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;
	}
	
	@Override
	public void play() {
		cd.play();
	}

}
  • 测试
package com.test.soundsSystem;

import org.junit.Test;
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 {
	
	@Autowired
	private MediaPlayer mp;

	@Test
	public void test2() {
		mp.play();
	}
}

  • 运行结果:
    Junit窗口绿条
    console控制台输出 SgtPeppers play
注意

CompactDisc的实现类有3种情况:

  • 有1个
  • 0个
  • 有多个
1个

如果存在一个CompactDisc的实现类bean可以注入,那么注入成功。

0个

如果没有CompactDisc的实现类bean,那么在创建application context时会抛出异常。

可以在@Autowired中使用required=false,解决抛出异常的问题,但是此时这个属性变量就没有装配(注入),是null,要注意对null的判断。

@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;
    
    @Autowired(required=false)
    public CDPlayer(CompactDisc cd) {
        this.cd = cd;
    }
}
多个

也是抛出异常

@inject

除了使用@Autowired进行装配,还可以使用注解@inject,使用方法和@Autowired一样。可以在构造器、setter方法和普通方法上使用。(能不能在属性上用不知道)

基于java装配bean

通常,我们使用上面的自动装配的方式,但是,不是任何情况都可以使用自动装配的方式,例如使用第三方库时,就不能在它的类上使用@Component和@Autowired。

需要完成创建bean实例并放入application context中,以及装配bean这2个任务。

基于java的显示配置JavaConfig是一种很好的显示配置方式。

现在,基于java的装配,不能使用@ComponentScan、@Component和@Autowired这3个注解。

使用注解@Configuration注解@Bean

  • @Configuration:在JavaConfig类上使用。
  • @Bean:在JavaConfig类的方法上使用。
@Bean的使用

在JavaConfig类的方法上使用

使用@Bean完成创建bean实例并放入application context中,以及装配bean这2个任务。

创建bean实例并放入application context中
@Bean
public CompactDisc sgtPeppers() {
	return new SgtPeppers();
}

@Bean的作用

  • 表示这个方法返回一个CompactDisc bean实例。
  • 让spring执行这个sgtPeppers()方法,把创建的bean实例放到application context中。

注意

  • 方法体内要有创建bean实例的逻辑代码。
  • 创建的bean实例的id是方法名,也就是sgtPeppers。
  • 如果想要修改bean的id,有2种方式:
    • 第一种,修改方法名。
    • 第二种,@Bean注解那么属性可以设置id。
@Bean("newId")
public CompactDisc sgtPeppers() {
	return new SgtPeppers();
}
装配bean

装配bean有2种方式

  • 方法1
@Configuration
public class CDPlayerConfig {

	@Bean
	public CompactDisc sgtPeppers() {
		return new SgtPeppers();
	}
	
	@Bean
	public CDPlayer cdPlayer() {
		return new CDPlayer(sgtPeppers());
	}
}

对于cdPlayer()方法体中的sgtPeppers()方法,不是创建了新的SgtPeppers实例,而是application context中的SgtPeppers实例,因为加上了@Bean,spring会起到了拦截作用。
首先,spring调用sgtPeppers()得到SgtPeppers实例,把SgtPeppers实例放入application context中,接着spring调用cdPlayer(),把application context中的SgtPeppers实例作为参数,执行sgtPeppers()方法,并没有创建新的SgtPeppers实例。

  • 方法2(推荐使用)
@Configuration
public class CDPlayerConfig {

	@Bean
	public CompactDisc sgtPeppers() {
		return new SgtPeppers();
	}
	
	@Bean
	public MediaPlayer cdPlayer(CompactDisc compactDisc) {
		return new CDPlayer(compactDisc);
	}
}
demo
  1. 定义接口和实现类bean
    接口和上面的一样,这里不再重复写,实现类去掉@Component和@Autowired
package com.test.wiringWithJava;

public class SgtPeppers implements CompactDisc {
	
	public void play() {
		System.out.println("SgtPeppers play");
	}

}
package com.test.wiringWithJava;

public class CDPlayer implements MediaPlayer {

	private CompactDisc cd;

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

}
  1. 定义JavaConfig类
    去掉@ComponentScan
package com.test.wiringWithJava;

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

@Configuration
public class CDPlayerConfig {

	@Bean
	public CompactDisc sgtPeppers() {
		return new SgtPeppers();
	}
	
//	@Bean
//	public CDPlayer cdPlayer() {
//		return new CDPlayer(sgtPeppers());
//	}
	
	@Bean
	public MediaPlayer cdPlayer(CompactDisc cd) {
		return new CDPlayer(cd);
	}
}
  1. 测试
    和上面的一样
  • 运行结果:
    Junit窗口绿条
    console控制台输出 SgtPeppers play

基于xml装配bean

可以在xml文件中完成bean的创建和装配bean。
建议使用自动化装配和基于java的装配,xml的方式作为可以维护已有的xml文件即可。
xml方式的缺点:

  • xml文件复杂。相对于基于java的显式装配,完成相同功能时,xml要更加复杂。下面是没有任何功能下的xml,可以看到,很复杂。
  • xml容易出错。在定义时,class是字符串类型的类的全限定类名,容易出错。
  • 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">

  <!--spring xml code-->

</beans>

使用xml的方式就是不能使用@Component和@Autowired,@ComponentScan。就是不能使用注解。

下面详细说明关于xml完成创建bean和装配bean的方式

创建bean

使用标签,class属性,class值是字符串类型的bean的全限定类名。

<bean class="com.test.soundsSystem.SgtPeppers" />

这时bean的id是由全限定类名决定,id是com.test.wiringWithJava.SgtPeppers#0。如果定义下一个SgtPeppers的,那么id是com.test.wiringWithJava.SgtPeppers#1。

定义id

<bean id="compactDisc" class="com.test.soundsSystem.SgtPeppers" />
装配bean

在装配bean时,要用到bean的id,所以建议:在定义时,如果是作为被依赖的bean,那么定义id,否则不用定义id。

装配bean的方式:

  • 基于构造器的方式
  • 基于setter的方式

其中基于构造器的方式也有2种方式:

  • <constructor-arg />
  • c-命名空间

基于setter的方式也有2种方式:

  • <property />
  • p-命名空间

Spring为提供了c-命名空间作为替代方案,为提供了p-命名空间作为替代方案。

构造器方式

接口和实现类和之前的一样,只不过把注解都去掉。

构造器方式可以注入:

  • 引用
  • 字面量
  • 集合(只有支持,c-命名空间不支持)
注入引用
  • <constructor-arg />
    使用属性ref,ref的值是要被依赖的bean的id。
<bean id="cdPlayer" class="com.test.soundsSystem.CDPlayer">
    <constructor-arg ref="compactDisc" />
</bean>
  • c-命名空间
    使用c-命名空间需要添加新的声明。
<?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">

  <!--code-->

</beans>

以下是使用c-命名空间的装配

public class CDPlayer implements MediaPlayer {

	private CompactDisc cd;

	public CDPlayer(CompactDisc cd) {
		this.cd = cd;
	}
	
	@Override
	public void play() {
		cd.play();
	}
}
<bean id="cdPlayer" class="com.test.soundsSystem.CDPlayer" c:cd-ref="compactDisc">
</bean>

在这里插入图片描述

  • c: :c:是c-命名空间要用的。
  • cd:cd是构造器中的参数名称。
  • -ref:-ref是注入引用使用的。

如果在重构代码时,把参数名修改了,那么这个xml会无效。下面是使用索引的方式。

<bean id="cdPlayer" class="com.test.soundsSystem.CDPlayer" c:_0-ref="compactDisc">
</bean>
  • 0:0表示第一个参数,0的前面有下划线_是因为数字不能作为属性的开头。

下一个参数就是c:_1-ref

如果只有一个参数,那么可以省略为以下代码,去掉索引。

<bean id="cdPlayer" class="com.test.soundsSystem.CDPlayer" c:_-ref="compactDisc">
</bean>
注入字面量

先定义一个新的类。

public class BlankDisc implements CompactDisc {
	private String title;
	
	private String artist;
	
	public BlankDisc(String title, String artist) {
		super();
		this.title = title;
		this.artist = artist;
	}

	@Override
	public void play() {
		System.out.println("play " + title + " by " + artist);
	}

}
  • <constructor-arg />
    使用value属性注入。
<bean id="compactDisc" class="com.test.soundsSystem.BlankDisc">
    <constructor-arg value="Field of hope" />
    <constructor-arg value="Seed" />
</bean>
  • c-命名空间
    c-命名空间注入字面量和注入引用不同之处就是去掉了-ref。
<bean id="compactDisc" class="com.test.soundsSystem.BlankDisc" c:_title="Field of hope" c:_artist="Seed">

</bean>

使用索引的方式:

<bean id="compactDisc" class="com.test.soundsSystem.BlankDisc" c:_0="Field of hope" c:_1="Seed">

</bean>

假设这个构造器只有一个参数,可以省略为以下代码。

<bean id="compactDisc" class="com.test.soundsSystem.BlankDisc" c:_="Field of hope">

</bean>
装配集合

如果构造器的参数是List类型。在里面使用或标签

  • <value>:集合元素是字面量

  • <ref bean=“bean id” />:集合元素是引用

  • 装配String类型的List

实现类

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;
	}

	@Override
	public void play() {
		System.out.println("play " + title + " by " + artist);
		for(String track : tracks) {
		    System.out.println("-track " + track)
		}
	}

}
<bean id="compactDisc" class="com.test.soundsSystem.BlankDisc">
    <constructor-arg value="Field of hope" />
    <constructor-arg value="Seed" />
    <constructor-arg>
        <list>
            <value>Numb</value>
            <value>Burn</value>
            <!--...-->
        </list>
    </constructor-arg>
</bean>
  • 装配引用类型的List

实现类

public class BlankDisc implements CompactDisc {
	private String title;
	
	private String artist;
	
	private List<String> tracks;
	
	public BlankDisc(String title, String artist, List<CompactDisc> tracks) {
		this.title = title;
		this.artist = artist;
		this.tracks = tracks;
	}

	@Override
	public void play() {
		System.out.println("play " + title + " by " + artist);
		for(CompactDisc track : tracks) {
		    System.out.println("-track " + track)
		}
	}
}
<bean id="compactDisc" class="com.test.soundsSystem.BlankDisc">
    <constructor-arg value="Field of hope" />
    <constructor-arg value="Seed" />
    <constructor-arg>
        <list>
            <ref bean="bean_id_1" />
            <ref bean="bean_id_2" />
            <!--...-->
        </list>
    </constructor-arg>
</bean>

构造器的参数也可以是Set类型,如果是Set类型,使用标签替换上面的标签,其他的和标签的用法一样。

或是都可以装配List、Set和数组。

setter方式

我们可以使用setter方法的方式注入属性。

有2种方式:

  • <property >
  • p-命名空间

属性注入可以注入引用和字面量。

注入引用
  • 实现类
public class CDPlayer implements MediaPlayer {
    private CompactDisc compactDisc;

    public void setCompactDisc(CompactDisc compactDisc) {
        this.compactDisc = compactDisc;
    }

    @Override
    public void paly() {
        compactDisc.play();
    }
}
  • <property >
    使用ref属性
<bean id="compactDisc" class="com.test.soundsSystem.BlankDisc">
    <!-- ... -->
</bean>

<bean class="soundsystem.CDPlayer">
    <property name="compactDisc" ref="compactDisc" />
</bean>

对property标签的属性进行说明:

  1. name:类的属性名。
  2. ref:定义的bean的id。
  • p-命名空间
    使用p-命名空间,需要引入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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!--code-->

</beans>
<bean class="soundsystem.CDPlayer" p:compactDisc-ref="compactDisc">

</bean>

在这里插入图片描述
p-命名空间属性的语法规则如下:

  1. p::p:是p-命名空间需要的。
  2. compactDisc:类的属性名。
  3. -ref:表明后面的字符串是应用,是bean的id。
  4. =“compactDisc”:compactDisc是bean的id。
注入常量
  • 实现类
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;
	}

	@Override
	public void play() {
		System.out.println("play " + title + " by " + artist);
		for(String track : tracks) {
		    System.out.println("-track " + track)
		}
	}
}
  • <property >
<bean class="soundsystem.BlankDisc">
    <property name="title" value="Field of hope" />
    <property name="artist" value="Seed" />
    <property name="tracks">
        <value>Numb</value>
        <value>Burning</value>
        <!-- ... -->
    </property>
</bean>

对property标签的属性进行说明:

  1. name:类的属性名。
  2. value:后面是字符串值,是字面量,不是引用。
  • p-命名空间
<bean class="soundsystem.BlankDisc" p:title="Field of hope" p:artist="Seed">
    <property name="tracks">
        <value>Numb</value>
        <value>Burning</value>
        <!-- ... -->
    </property>
</bean>

和注入引用的区别是没有了-ref。
p-命名空间不能装配集合。
如果想简化标签装配集合,可以使用util-命名空间

  • util-命名空间

要使用util-命名空间,需要引入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">
    
    <!--code-->
    
</beans>
<util:list id="trackList">
    <value>Numb</value>
    <value>Burning</value>
    <!-- ... -->
</util:list>

<bean class="soundsystem.BlankDisc" p:title="Field of hope" p:artist="Seed" p:tracks-ref="trackList">

</bean>

混合配置

我们可以使用自动化配置,或者基于Java或xml的显示配置来装配bean。因为这三种方式并不互斥,所以,可以混合使用。
建议使用自动化配置,如果需要显示配置,也建议使用JavaConfig,在需要的时候才使用xml。

在使用自动化配置时,需要使用显示配置启动组建扫描(@ComponentScan或<context:component-scan >)

现在有一个问题,如果配置的bean太多,那么在一个文件中完成所有的bean的配置的话,维护起来很麻烦。所以,可以在一个配置的文件中引入其他的配置文件,这样,就可以把多个bean的配置分开到多个配置文件中了。

有2种情况:

  • 在JavaConfig中引入JavaConfig和xml
  • 在xml中引入JavaConfig和xml

通常,使用一个根的JavaConfig或根的xml,来引入所有的bean的配置,然后,在这个根文件中开启组建扫描。

在JavaConfig引入JavaConfig和xml
引入JavaConfig

使用注解@Import

语法:@Import({xxxConfig.class, yyyConfig.class, …})
如果只引入一个文件,那么@Import中的{}可以省略

@Configuration
public class CDPlayerConfig {
	@Bean
	public CDPlayer cdPlayer(CompactDisc compactDisc) {
		return new CDPlayer(compactDisc);
	}
}
@Configuration
public class CDConfig {
	@Bean
	public CompactDisc sgtPeppers() {
		return new SgtPeppers();
	}
}
@Configuration
@Import({CDPlayerConfig.class, CDConfig.class})
public class SoundSystemConfig {

}
引入xml

使用注解@ImportResource
语法:@ImportResource(“classpath:xml文件相对于JavaConig文件的路径”)

CDPlayerConfig存在,CompactDisc在xml配置。xml文件叫cd-config.xml。

<bean id="compactDisc" class="com.test.soundsSystem.BlankDisc">
    <constructor-arg value="Field of hope" />
    <constructor-arg value="Seed" />
    <constructor-arg>
        <list>
            <value>Numb</value>
            <value>Burn</value>
            <!--...-->
        </list>
    </constructor-arg>
</bean>
@Configuration
@Import(CDPlayerConfig.class)
@ImportResource("classpath:cd-config.xml")
public class SoundSystemConfig {

}
在xml中引入JavaConfig和xml
引入xml

使用标签<import>
语法:<import resource=“相对于根xml的需要引入的xml配置文件的路径” />

cd-config.xml

<bean id="compactDisc" class="com.test.soundsSystem.BlankDisc">
    <constructor-arg value="Field of hope" />
    <constructor-arg value="Seed" />
    <constructor-arg>
        <list>
            <value>Numb</value>
            <value>Burn</value>
            <!--...-->
        </list>
    </constructor-arg>
</bean>

cdPlayer-config.xml

<bean id="cdPlayer" class="com.test.soundsSystem.CDPlayer" c:_-ref="compactDisc">
</bean>

soundSystem.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="cd-config.xml" />
  <import resource="cdPlayer-config.xml" />

</beans>
引入JavaConfig

引入JavaConfig的方式是把JavaConfig作为bean在xml中配置。

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

cdPlayer-config.xml

<bean id="cdPlayer" class="com.test.soundsSystem.CDPlayer" c:_-ref="compactDisc">
</bean>

soundSystem.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 class="soundSystem.CDConfig" />
  <import resource="cdPlayer-config.xml" />

</beans>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值