博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring核心 装配Bean
阅读量:5820 次
发布时间:2019-06-18

本文共 18819 字,大约阅读时间需要 62 分钟。

Spring配置的可选方案

Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系。当描述bean如何进行装配时,Spring具有非常大的灵活性,它提供了三种主要的装配机制:

  • 在XML中进行显式配置

  • 在Java中进行显式配置

  • 隐式的bean发现机制和自动装配

尽可能地使用自动配置的机制。显式配置越少越好。当你必须要显式配置bean的时候(比如,有些源码不是由你来

维护的,而当你需要为这些代码配置bean的时候),推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时,才应该使用XML

自动化装配bean

Spring从两个角度来实现自动化装配:

  • 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean

  • 自动装配(autowiring):Spring自动满足bean之间的依赖

组件扫描和自动装配组合在一起就能发挥出强大的威力,它们能够将显式配置降低到最少

创建可被发现的bean

CompactDisc接口在Java中定义了CD的概念

package soundsystem;public interface CompactDisc{    void play();}

CompactDisc的具体内容并不重要,重要的是你将其定义为一个接口。作为接口,它定义了CD播放器对一盘CD所能进行的操作。它将CD播放器的任意实现与CD本身的耦合降低到了最小的程度

带有@Component注解的CompactDisc实现类SgtPeppers

package soundsystem;import org.springframework.stereotype.Component;@Componentpublic 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);    }}

SgtPeppers类上使用了@Component注解。这个简单的注解表明SgtPeppers类会作为组件类,并告知Spring要为这个类创建bean。没有必要显式配置SgtPeppersbean,因为这个类使用了@Component注解,所以Spring会为你把事情处理妥当

不过,组件扫描默认是不启用的。我们还需要显式配置一下Spring,从而命令它去寻找带有@Component注解的类,并为其创建bean

@ComponentScan注解启用了组件扫描

以下程序的配置类展现了完成这项任务的最简洁配:

package soundsystem;import org.springframework.context.annotation.componentScan;import org.springframework.context.annotation.Con;    @Component@ComponentScanpublic class CDPlayerConfig{}

类CDPlayerConfig通过Java代码定义了Spring的装配规则。观察可知,CDPlayerConfig类并没有显式地声明任何bean,只不过它使用了@ComponentScan注解,这个注解能够在Spring中启用组件扫描

如果没有其他配置的话,@ComponentScan默认会扫描与配置类相同的包。因为CDPlayerConfig类位于soundsystem包中,因此Spring将会扫描这个包以及这个包下的所有子包,查找带有@Component注解的类。这样的话,就能发现CompactDisc,并且会在Spring中自动为其创建一个bean

通过XML启用组件扫描

如更倾向于使用XML来启用组件扫描的话,那么可以使用Spring context命名空间的<context:component-scan>元素。以下程序展示了启用组件扫描的最简洁XML配置:

测试组件扫描能够发现CompactDisc

package soundsystem;import static org.junit.Assert.*;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_139772[test]     public void cdShouldNotBeNull()    {        assertNotNull(cd);    }}

CDPlayerTest使用了Spring的SpringJUnit4ClassRunner,以便在测试开始的时候自动创建Spring的应用上下文。注解@ContextConfiguration会告诉它需要在CDPlayerConfig中加载配置。因为CDPlayerConfig类中包含了@ComponentScan,因此最终的应用上下文中应该包含CompactDiscbean

在测试代码中有一个CompactDisc类型的属性,并且这个属性带有@Autowired注解,以便于将CompactDiscbean

注入到测试代码之中。最后,会有一个简单的测试方法断言cd属性不为null。如果它不为null的话,就意味着Spring能够发现CompactDisc类,自动在Spring上下文中将其创建为bean并将其注入到测试代码之中

为组件扫描的bean命名

Spring应用上下文中所有的bean都会给定一个ID。前面的例子中,尽管没有明确地为SgtPeppersbean设置ID,但Spring会根据类名为其指定一个ID。具体来讲,这个bean所给定的ID为sgtPeppers,也就是将类名的第一个字母变为小写

若想为这个bean设置不同的ID,则需将期望的ID作为值传递给@Component注解:

@Component("lonelyHeartsClub")public class SgtPeppers implements CompactDisc{    ...}

另外一种为bean命名的方式,使用Java依赖注入规范(Java Dependency Injection)中所提供的@Named注解来为bean设置ID:

package soundsystem;import javax.inject.Named;@Named("lonelyHeartsClub")public class SgtPeppers implements CompactDisc{    ...}

设置组件扫描的基础包

为了指定不同的基础包,所需要在@ComponentScan的value属性中指明包的名称:

@Configuration@ComponentScan("soundsystem")public class CDPlayerConfig{}

若需更加清晰地表明你所设置的是基础包,通过basePackages属性进行配置:

@Configuration@ComponentScan(basePackages = "soundsystem")public class CDPlayerConfig{}

如果需要可以设置多个基础包,只需要将basePackages属性设置为要扫描包的一个数组即可:

@Configuration@ComponentScan(basePackages = {"soundsystem", “videos”})public class CDPlayerConfig{}

上面例子中,所设置的基础包是以String类型表示的。这是可行的,但这种方法是类型不安全(not type-safe)的。如进行代码重构,那么所指定的基础包可能会出现错误

除了将包设置为简单的String类型之外,@ComponentScan提供的另外一种方法,将其指定为包中所包含的类或接口:

@Configuration@ComponentScan(basePackageClasses = {CDPlayer.class, DVDPlayer.class})public class CDPlayerConfig{}

通过为bean添加注解实现自动装配

自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean。为了声明要进行自动装配,我们可以借助Spring的@Autowired注解

下述程序CDPlayer类。它的构造器上添加了@Autowired注解,这表明当Spring创建CDPlayerbean的时候,会通过这个构造器来进行实例化并且会传入一个可设置给CompactDisc类型的bean

通过自动装配,将一个CompactDisc注入到CDPlayer之中:

package soundsystem;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;@Componentpublic class CDPlayer implement MediaPlayer{    private CompactDisc cd;        @Autowired    public CDPlayer(CompactDisc cd)    {        this.cd = cd;    }        public void play    {        cd.play();    }}

@Autowired注解不仅能够用在构造器上,还能用在属性的Setter方法上。比如说,如果CDPlayer有一个setCompactDisc()方法,那么可以采用如下的注解形式进行自动装配:

@Autowiredpublic void setCompactDisc(CompactDisc cd)

@Autowired注解可以用在类的任何方法上。假设CDPlayer类有一个insertDisc()方法,那么@Autowired能够像在setCompactDisc()上那样,发挥完全相同的作用:

@Autowiredpublic void insertDisc(CompactDisc cd){    this.cd = cd;}

不管是构造器、Setter方法还是其他的方法,Spring都会尝试满足方法参数上所声明的依赖。假如有且只有一个bean匹配依赖需求的话,那么这个bean将会被装配进来

如果没有匹配的bean,那么在应用上下文创建的时候,Spring会抛出一个异常。为了避免异常的出现,你可以将@Autowired的required属性设置为false:

@Autowiredpublic CDPlayer(CompactDisc cd){    this.cd = cd;}

将required属性设置为false时,Spring会尝试执行自动装配,若没有匹配的bean,Spring将会让这个bean处于未装配的状态。但把required属性设置为false时,需要谨慎对待。如果代码中没有进行null检查,处于未装配状态的属性可能出现NullPointerException

@Autowired是Spring特有的注解。如果不愿代码中到处使用

Spring的特定注解来完成自动装配任务,可考虑替换为@Inject:

package soundsystem;import javax.inject.Inject;import javax.inject.Named;@Namedpublic class CDPlayer{    ...    @Inject    public CDPlayer(CompactDisc cd)    {        this.cd = cd;    }    ...}

@Inject注解来源于Java依赖注入规范,该规范同时还定义了@Named注解。在自动装配中,Spring同时支持@Inject和

@Autowired。尽管@Inject和@Autowired之间有着一些细微的差别,但是在大多数场景下,是可以互相替换的

验证自动装配

图片描述

除了注入CompactDisc,还将CDPlayerbean注入到测试代码的player成员变量之中(它是更为通用的MediaPlayer类型)。在play()测试方法中,我们可以调用CDPlayer的play()方法,并断言它的行为与预期一致

在测试代码中使用System.out.println()。因此,该样例中使用了StandardOutputStreamLog,是来源于System Rules库()的一个JUnit规则,该规则能够基于控制台的输出编写断言。SgtPeppers.play()方法的输出将被发送到控制台上

通过Java代码装配bean

如想将第三方库中的组件装配到你的应用中,在这种情况下无法通过在它的类上添加@Component和@Autowired注解的方法实现自动化装配

JavaConfig与其他的Java代码存在区别,在概念上,它与应用程序中的业务逻辑和领域代码不同的。尽管都使用相同的语言进行表述,但JavaConfig是配置代码。这意味着它不应该包含任何业务逻辑,JavaConfig也不应该侵入到业务逻辑代码之中。尽管不是必须的,但通常会将JavaConfig放到单独的包中,使它与其他的应用程序逻辑分离开来,这样对于它的意图就不会产生困惑了

创建配置类

创建JavaConfig类的关键在于为其添加@Configuration注解,@Configuration注解表明这个类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节

package soundsystem;import org.springframework.context.annotation.Configuration;@Configurationpublic class CDPlayerConfig{    ...}

到此为止,都是依赖组件扫描来发现Spring应该创建的bean。尽管可以同时使用组件扫描和显式配置,但在本节更加关注于显式配置,因此将CDPlayerConfig的@ComponentScan注解移除掉了。移除了@ComponentScan注解,此时的CDPlayerConfig类就没有任何作用了。如现在运行CDPlayerTest,测试失败,并出现BeanCreation-Exception异常。测试期望被注入CDPlayer和CompactDisc,但这些bean根本就没有创建,因为组件扫描不会发现它们。下一节,将展现如何使用JavaConfig装配CDPlayer和CompactDisc

声明简单的bean

要在JavaConfig中声明bean,需编写一个创建所需类型实例的方法,然后给这个方法添加@Bean注解。如下代码声明了CompactDisc bean:

@Beanpublic CompactDisc sgtPeppers(){    return new SgtPeppers();}

@Bean注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了最终产生bean实例的逻辑

默认情况下,bean的ID与带有@Bean注解的方法名是一样的。在本例中,bean的名字将会是sgtPeppers。如果你想为其设置成一个不同的名字的话,那么可以重命名该方法,也可以通过name属性指定一个不同的名字:

@Bean(name= "lonelyHeartsClubBand")public CompactDisc sgtPeppers(){    return new SgtPeppers();}

借助JavaConfig实现注入

前面所声明的CompactDisc bean非常简单,自身没有其他依赖。现在,需要声明依赖于CompactDisc的CDPlayer bean。在JavaConfig中装配bean的最简单方式就是引用创建bean的方法。如下就是一种声明CDPlayer的可行方案:

@Beanpublic CDPlayer cdPlayer(){    return new CDPlayer(sgtPeppers());}

这个方法会创建一个bean实例并将其注册到Spring应用上下文中。所创建的bean ID为cdPlayer,与方法的名字相同。cdPlayer()的方法体与sgtPeppers()稍微有些区别。在这里并没有使用默认的构造器构建实例,而是调用了需要传入CompactDisc对象的构造器来创建CDPlayer实例。看起来,CompactDisc是通过调用sgtPeppers()得到的,但情况并非完全如此。因为sgtPeppers()方法上添加了@Bean注解,Spring将会拦截所有对它的调用,并确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用

@Beanpublic CDPlayer cdPlayer(){    return new CDPlayer(sgtPeppers());}@Beanpublic CDPlayer anotherCDPlayer(){    return new CDPlayer(sgtPeppers());}

默认情况下,Spring中的bean都是单例的,并没必要为第二个CDPlayer bean创建完全相同的SgtPeppers实例。所以,Spring会拦截对sgtPeppers()的调用并确保返回的是Spring所创建的bean,也就是Spring本身在调用sgtPeppers()时所创建的CompactDiscbean。因此,两个CDPlayer bean会得到相同的SgtPeppers实例

@Beanpublic CDPlayer cdPlayer(CompactDisc compactDisc){    return new CDPlayer(sgtPeppers());}

在这里,cdPlayer()方法请求一个CompactDisc作为参数。当Spring调用cdPlayer()创建CDPlayerbean的时候,它会自动装配一个CompactDisc到配置方法之中。然后,方法体就可以按照合适的方式来使用它。借助这种技术,cdPlayer()方法也能够将CompactDisc注入到CDPlayer的构造器中,而且不用明确引用CompactDisc的@Bean方法

通过这种方式引用其他的bean通常是最佳的选择,因为它不会要求将CompactDisc声明到同一个配置类之中。在这里甚至没有要求CompactDisc必须要在JavaConfig中声明,实际上它可以通过组件扫描功能自动发现或者通过XML来进行配置

可以将配置分散到多个配置类、XML文件以及自动扫描和装配bean之中,只要功能完整健全即可。不管CompactDisc是采用什么方式创建出来的,Spring都会将其传入到配置方法中,并用来创建CDPlayer bean

通过XML装配bean

创建XML配置规范

在使用XML为Spring装配bean之前,你需要创建一个新的配置规范。在使用JavaConfig的时候,这意味着要创建一个带有@Configuration注解的类,而在XML配置中,这意味着要创建一个XML文件,并且要以<beans>元素为根

如上基本的XML配置已比同等功能的JavaConfig类复杂。在JavaConfig中只需要@Configuration,但在XML中,需要在配置文件的顶部声明多个XML模式(XSD)文件,这些文件定义了配置Spring的XML元素

借助Spring Tool Suite创建XML配置文件创建和管理Spring XML配置文件的一种简便方式是使用Spring Tool Suite()。在Spring Tool Suite的菜单中,选择File>New>Spring Bean Configuration File,能够创建Spring XML配置文件,并且可以选择可用的配置命名空间

用来装配bean的最基本的XML元素包含在spring-beans模式之中,在上面这个XML文件中,它被定义为根命名空间。<beans>是该模式中的一个元素,它是所有Spring配置文件的根元素

声明一个简单的<bean>

要在基于XML的Spring配置中声明一个bean,我们要使用springbeans模式中的另外一个元素:<bean>。<bean>元素类似于JavaConfig中的@Bean注解。可以如下的方式声明CompactDiscbean:

这里声明了一个简单的bean,创建这个bean的类通过class属性来指定的,并且要使用全限定的类名

因没明确给定ID,所以这个bean将会根据全限定类名来进行命名。在本例中,bean的ID将会是“soundsystem.SgtPeppers#0”。其中,“#0”是一个计数的形式,用来区分相同类型的其他bean。如果你声明了另外一个SgtPeppers,并且没有明确进行标识,那么它自动得到的ID将会是“soundsystem.SgtPeppers#1”

通常来讲,更好的办法是借助id属性,为每个bean设置一个你自己选择的名字:

减少繁琐为了减少XML中繁琐的配置,只对那些需要按名字引用的bean(比如,你需要将对它的引用注入到另外一个bean中)进行明确地命名

借助IDE检查XML的合法性使用能够感知Spring功能的IDE,如Spring Tool Suite,能够在很大程度上帮助你确保Spring XML配置的合法性

借助构造器注入初始化bean

在Spring XML配置中,只有一种声明bean的方式:使用<bean>元素并指定class属性。Spring会从这里获取必要的信息来创建bean。但是,在XML中声明DI时,会有多种可选的配置方案和风格。具体到构造器注入,有两种基本的配置方案可供选择:

  • <constructor-arg>元素

  • 使用Spring 3.0所引入的c-命名空间

构造器注入bean引用

1.<constructor-arg>元素方案:

现已声明SgtPeppers bean,并且SgtPeppers类实现了CompactDisc接口,所以实际上已经一个可以注入到CDPlayerbean中的bean。所需做的是在XML中声明CDPlayer并通过ID引用SgtPeppers:

当Spring遇到这个<bean>元素时,会创建一个CDPlayer实例。<constructor-arg>元素会告知Spring要将一个ID

为compactDisc的bean引用传递到CDPlayer的构造器中

2.c-命名空间方案:

c-命名空间是在XML中更为简洁地描述构造器参数的方式。要使用它的话,必须要在XML的顶部声明其模式,如下所示:

在c-命名空间和模式声明之后,就可以使用它来声明构造器参数了,如下所示:

属性名以“c:”开头,也就是命名空间的前缀。接下来就是要装配的构造器参数名,在此之后是“-ref”,这是一个命名的约定,它会告诉Spring,正在装配的是一个bean的引用,这个bean的名字是compactDisc,而不是字面量“compactDisc”

图片描述

引用参数的名称有些怪异,因为需要编译代码时,将调试标志(debug symbol)保存在类代码中。如果优化构建过程,将调试标志移除掉,那么这种方式可能就无法正常执行。根本不用去标示参数的方案:

将字面量(literal value)注入到构造器中

迄今为止,所做的DI通常指的都是类型的装配——也就是将对象的引用装配到依赖于它们的其他对象之中——而有时需要的只是用一个字面量值来配置对象

1.<constructor-arg>元素方案:

package soundsystem;public class BlankDisc implements CompactDisc{    private String title;    private String artist;        public BlankDisc(String title, String artist)    {        this.title = title;        this.artist = artist;    }        public void play()    {        System.out.println("Playing" + title + "by" + artist);    }}

上述程序使用<constructor-arg>元素进行构造器参数的注入。没有使用“ref”属性来引用其他的bean,而使用了

value属性,通过该属性表明给定的值要以字面量的形式注入到构造器之中

2.c-命名空间方案:

引用构造器参数名:

通过参数索引装配相同的字面量值:

装配集合

含有磁道列表概念的BLankDisc

package soundsystem.collections;import java.ytil.List;import soundsystem.CompactDisc;public class BlankDisc implements CompactDisc{    private String title;    private String artist;    private List
tracks; public BlankDisc(String title, String artist, List
tracks) { this.title = title; this.artist = artist; this.tracks = tracks; } public void play() { System.out.println("Playing" + title + "by" + artist); for(String track : tracks) { System.out.println("-Track: " + track); } }}

这个变更会对Spring如何配置bean产生影响,在声明bean时,必须要提供一个磁道列表。较好的解决方法是提供一个磁道名称的列表。首先,可以使用<list>元素将其声明为一个列表:

Sgt. Pepper's Lonely Hearts Club Band
With a Little Help from My Friend
Lucy in the Sky with Diamonds
Getting Better
Fixing a Hole

其中,<list>元素是<constructor-arg>的子元素,这表明一个包含值的列表将会传递到构造器中。其中,<value>元素用来指定列表中的每个元素

也可使用<ref>元素替代<value>,实现bean引用列表的装配。假设有一个Discography类,构造器如下所示:

public Discography(String artist, List
cds){ ...}

采取如下的方式配置Discography bean:

...

在装配集合方面,<constructor-arg>比c-命名空间的属性更有优势。目前,使用c-命名空间的属性无法实现装配集合的功能。使用<constructor-arg>和c-命名空间实现构造器注入时,它们之间还有一些细微的差别

设置属性

使用Spring XML实现属性注入

设属性注入的CDPlayer如下所示:

package soundsystem;import org.springframework.beans.factory.annotation.Autowired;import soundsystem.CompactDisc;import soundsystem.MediaPlayer;public class CDPlayer implement MediaPlayer{    private CompactDisc compactDisc;        @Autowired    public CDPlayer(CompactDisc compactDisc)    {        this.compactDisc = compactDisc;    }        public void play    {        compactDisc.play();    }}

作为一个通用的规则,强依赖使用构造器注入,而对可选性的依赖使用属性注入

p-命名空间:

使用p-命名空间装配compactDisc属性:

图片描述

属性的名字使用了“p:”前缀,表明我们所设置的是一个属性。接下来就是要注入的属性名。最后,属性的名称以“-ref”结尾,这会提示Spring要进行装配的是引用,而不是字面量

将字面量注入到属性中

以下BlankDisc完全通过属性注入进行配置,而不是构造器注入。新的BlankDisc类如下所示:

package soundsystem.collections;import java.ytil.List;import soundsystem.CompactDisc;public class BlankDisc implements CompactDisc{    private String title;    private String artist;    private List
tracks; public setTitle(String title) { this.title = title; } public setArtistString artist) { this.artist = artist; } public setTracks(List
tracks) { this.tracks = tracks; } public void play() { System.out.println("Playing" + title + "by" + artist); for(String track : tracks) { System.out.println("-Track: " + track); } }}

借助<property>元素的value属性装配这些属性,内嵌<list>元素设置tracks属性:

Sgt. Pepper's Lonely Hearts Club Band
With a Little Help from My Friend
Lucy in the Sky with Diamonds
Getting Better
Fixing a Hole

使用p-命名空间:

Sgt. Pepper's Lonely Hearts Club Band
With a Little Help from My Friend
Lucy in the Sky with Diamonds
Getting Better
Fixing a Hole

与c-命名空间一样,装配bean引用与装配字面量的唯一区别在于是否带有“-ref”后缀。如果没有“-ref”后缀的话,所装配的就是字面量

不能使用p-命名空间来装配集合,没有便利的方式使用p-命名空间来指定一个值(或bean引用)的列表。但可以使用Spring util-命名空间中的一些功能来简化BlankDiscbean

首先,需要在XML中声明util-命名空间及其模式:

...

util-命名空间所提供的功能之一就是<util:list>元素,它会创建一个列表的bean。<util:list>可将磁道列表转移到BlankDisc bean之外,并将其声明到单独的bean之中,如下所示:

Sgt. Pepper's Lonely Hearts Club Band
With a Little Help from My Friend
Lucy in the Sky with Diamonds
Getting Better
Fixing a Hole

将磁道列表bean注入到BLANkDisc bean的tracks属性中:

元素 描述
<util:constant> 引用某个类型的public static域,并将其暴露为bean
<util:list> 创建一个java.util.List类型的bean,其中包含值或引用
<util:map> 创建一个java.util.Map类型的bean,其中包含值或引用
<util:properties> 创建一个java.util.properties类型的bean
<util:property-path> 引用一个bean的属性(或内嵌属性),并将其暴露为bean
<util:set> 创建一个java.util.Set类型的bean,其中包含值或引用

导入和混合配置

在JavaConfig中引用XML配置

现在假设CDPlayerConfig已经有些笨重,因此将其进行拆分。虽然目前只定义了两个bean,远远称不上复杂Spring配置。不过,在此假设两个bean已经算多了。一种方案是将BlankDisc从CDPlayerConfig拆分出来,定义到它自己的CDConfig类中,如下所示:

package soundsystem;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class CDConfig{    @Bean    public CompactDisc compactDisc()    {        return new SgtPeppers();    }}

上述程序的compactDisc()方法已经从CDPlayerConfig中移除掉了,现需要将这两个类组合在一起。一种方法就是

在CDPlayerConfig中使用@Import注解导入CDConfig:

package soundsystem;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中使用@Import,而是创建一个更高级别的SoundSystemConfig,在

这个类中使用@Import将两个配置类组合在一起:

package soundsystem;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中使用@Import,而是创建一个更高级别的SoundSystemConfig,在这个类中使用@Import将两个配置类组合在一起:

package soundsystem;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;@Configuration@Import({CDPlayerConfig.class, CDConfig.class})public class SoundSystemConfig{}

现已将CDPlayer的配置与BlankDisc的配置分开,假设(基于某些原因)希望通过XML来配置BlankDisc,如下所示:

Sgt. Pepper's Lonely Hearts Club Band
With a Little Help from My Friend
Lucy in the Sky with Diamonds
Getting Better
Fixing a Hole

使用@ImportResource注解同时加载XML配置和其他基于Java的配置,假设BlankDisc定义在名为cdconfig.

xml的文件中,该文件位于根类路径下,那么可以修改SoundSystemConfig,让它使用@ImportResource注解,如下所示:

package soundsystem;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;@Configuration@Import(CDPlayerConfig.class)@ImportResource("classpath:cd-config.xml")public class SoundSystemConfig{}

在XML配置中引用JavaConfig

在JavaConfig配置中,使用@Import和@ImportResource来拆分JavaConfig类。在XML中,使用import元素来拆分XML配置

设希望将BlankDisc bean拆分到自己的配置文件中,该文件名为cd-config.xml,这与之前使用@ImportResource是一样的。课在XML配置文件中使用<import>元素来引用该文件:

转载地址:http://jfzdx.baihongyu.com/

你可能感兴趣的文章
Linux日志文件总管——logrotate
查看>>
JAVA-JDK设置
查看>>
shell中数组的基本使用
查看>>
SAP HANA SQLScript
查看>>
在全国计算机等级考试中如何快速设置不用用户的同类设置
查看>>
Hadoop系列之十:Hadoop配置文件及常用配置参数详解(未完成)
查看>>
nginx
查看>>
使用iproute2配置force-onlink路由
查看>>
我终于明白了大师和凡夫的区别
查看>>
乔布斯辞去苹果CEO会对苹果产生什么影响?
查看>>
GRE over ipv4 详解
查看>>
华为配置MSTP及VRRP
查看>>
[CCNA图文笔记]-5-数据封装与解封装
查看>>
ESXI5上USB测试总结
查看>>
RHCS(一)之原理、搭建
查看>>
Java基础——集合框架(待整理)
查看>>
Docker Centos安装Openssh
查看>>
Linux下通用二进制安装包安装MySQL-5.6.37
查看>>
Usermod 命令详解
查看>>
sudo及其配置文件sudoers
查看>>