装配bean

三种方案:

在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设置名称,这个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 实例的逻辑

默认情况下, beanID与带有@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要将一个IDcompactDiscbean引用传递到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"/>














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值