Spring实战(第四版)——第二章 装配Bean

Spring实战(第四版)——第二章 装配Bean


本章主要内容

  • 声明bean
  • 构造器注入和Setter方法注入
  • 装配bean
  • 控制bean的创建和销毁

在Spring中,对象无需自己查找或者创建与其所关联的其他对象。相反,容器负责把需要相互协作的对象引用赋予各个对象。例如,一个订单管理组件需要信用卡认证组件,但它不需要自己创建信用卡认证组件。订单管理组件只需要声明自己两手空空,容器就会主动赋予它一个信用卡认证组件。创建应用对象之间写作关系的行为通常称为装配(wiring),这也是依赖注入(DI)的本质。

2.1 Spring配置的可选方案

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

  • 在XML中进行显示配置
  • 在Java中进行显示配置
  • 隐式的bean发现机制和自动装配

作者建议是尽可能地使用自动配置的机制。显示配置越少越好。当你必须要显示配置bean的时候(比如,有些源码不是由你来维护的,而当你需要为这些代码配置bean的时候),推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时,才应该使用XML。

2.2 自动化装配Bean

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

  • 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
  • 自动装配(autowiring):Spring自动满足bean之间的依赖。

组件扫描和自动装配组合在一起就能发挥出强大的威力,它们能够将你的显示配置降低到最少。为了阐述组件扫描和自动装配,我们需要创建几个bean,它们代表一个影像系统中的组件。首先创建CompactDisc类,Spring会发现它并将其创建为一个bean。然后会创建一个CDPlayer类,让Spring发现它,并将CompactDisc bean注入进来。

2.2.1 创建可被发现的bean
上面说到的两个类CD类和CD播放器类,CD播放器依赖于CD才能完成使命。
CD定义如下:

package soundsystem;

public interface CompactDisc {
    void play();
}

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

package soundsystem;
import org.springframework.stereotype.Component;
@Component
public class SgtPeppers implements CompactDisc {

    private String title = "Sgt. Peooers's Lonely Hearts Club Band";
    private String artist = "The Beatles";

    public void play() {
        System.out.println("Play "+ title + "By" + artist);
    }
}

和CompactDisc接口一样,SgtPeppers 的具体内容并不重要。你需要注意的就是SgtPeppers 类上使用了@Component注解。这个简单的注解表明该类会作为组件类,并告知Spring要为这个类创建bean。没有必要显示配置SgtPeppers bean,因为这个类使用了@Component注解,所以Spring会为你把事情处理妥当。不过,组件扫描默认是不启用的。我们需要显示配置一下Spring,从而命令它去寻找带有@Component注解的类,并为其创建bean。

package soundsystem;

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

@Configuration
@ComponentScan
public class CDPlayerConfig {
}

类CDPlayerConfig通过Java代码定义了Spring的配置规则。我们可以看到CDPlayerConfig类并没有显示地声明任何bean,只不过它使用了@ComponentScan注解,这个注解能够在Spring中启用组件扫描。如果没有其他配置的话,@ComponentScan默认会扫描与配置类相同的包以及该包下的所有子包,查找带有@Component注解的类,并Spring自动为其创建一个bean。如果更加倾向于使用XML来启用组件扫描,可以在XML配置文件中中使用Spring context命名空间的< context : component-scan base-package = “包名”>来启用组件扫描。
最后我们来一个测试类CDPlayerTest(PS:Junit4的jar文件,请升级到4.12及以上) :

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
    public void cdShuoldNotBeNull(){
        assertNotNull(cd);
    }
}

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

2.2.2 为组件扫描的bean命名
Spring上下文中所有的bean都会给定一个ID,前面的例子中,虽然我们没有明确的为SgtPeppers 的bean设置ID,但是Spring会根据类名为其指定一个ID。一般为将类名的第一个字母小写,sgtPeppers。
如果想为bean设置不同的ID,可以通过下面两种方式:

@Component("自己为bean取的ID名称")
public class SgtPeppers implements CompactDisc {
...
}

第二种:

import javax.inject.Named;

@Named("自己为bean取的ID名称")
public class SgtPeppers implements CompactDisc {
...
}

2.2.3 设置组件扫描的基础包
到目前为止,我们没有给@ComponentScan设置任何属性,按照默认规则,它会以配置类所在的包作为基础包(base package)来扫描组件。但是当我们需要扫描其他包时,又该怎么做呢?
为了满足上面提到的需求,我们只需要为@ComponentScan的value属性指定包的名称即可:

//一、直接设置
@Configuration
@ComponentScan("soundsystem")
public class CDPlayerConfig{}

//二、更加清晰表达设置的是基础包,使用basePackages属性
@Configuration
@ComponentScan(basePackages = "soundsystem")
public class CDPlayerConfig{}

//三、设置多个基础包,将basePackages属性设置为一个数组即可
@Configuration
@ComponentScan(basePackages = {"soundsystem", "video"})
public class CDPlayerConfig{}

上面的例子中,所设置的基础包是以String类型表示的,可以使可以,但是这样做是类型不安全的(not type-safe)。如果想重构代码的话,那么所指定的基础包可能就会出现错误了。除了简单的String类型外,@ComponentScan还提供了另外一种方法:指定为包中所包含的类或接口

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

这里,basePackages属性呗替换成basePackageClasses。不是再使用String类型的名称来指定包,为basePackageClasses属性所设置的数组中包含了类,这些类所在的包将会作为组件扫描的基础包

2.2.4 通过为bean添加注解实现自动装配
简单来说,自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean。为了声明要进行自动装配,我们可以借助Spring的 @Autowired注解。例如,下面这个例子,CDPlayerConfig类,它的构造方法上添加@Autowired注解,这表明当Spring创建CDPlayer bean的时候,会通过这个构造器来进行实例化并且会传入一个可以设置给CompactDisc类型的bean。不仅仅是构造方法,还能在属性的Setter方法上以及类的其他方法上使用注解:

package soundsystem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CDPlayer {

    private CompactDisc cd ;

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

    //下面这两个方法只是为了说明@Autowired注解可以在方法上使用
    @Autowired
    public void setCompactDisc(CompactDisc cd ){
        this.cd = cd ;
    }

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

如果在使用@Autowied注解时,没有匹配的bean,那么在上下文创建的时候,Spring就会抛出一个异常,为避免异常的出现,可以将@Autowired的required属性设置为false。当设置为false时,Spring会尝试执行自动装配,如果没有匹配的bean,Spring会让这个bean处于未装配的状态。在把required属性设置为false时,需要谨慎对待,如果你的代码中没有进行null检查的话,这个处于未装配的属性就可能会出现NullPointerException。
@Autowired是Spring特有的注解,如果不想用,可以考虑用@Inject代替它,@Inject注解来源于Java依赖注入规范,该规范还同时为我们定义了@Named注解,在自动装配中,@Autowired和@Inject两者都支持。

2.3 通过Java代码装配Bean

尽管在很多场景下通过组件扫描和自动装配实现Spring的自动化装配是更为推荐的方式,但有时候自动化配置的方案是行不通的,因此需要明确配置Spring。比如说,你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component和@Autowired注解的,因此就不能使用自动化装配的方案。此时必须采用显示配置,即使用Java和XML,下面开始介绍JavaConfig的配置
2.3.1创建配置类
在上面的程序中,我们见识到JavaConfig,让我们重温一下CDPlayerConfig类:

package soundsystem;

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

@Configuration
@ComponentScan
public class CDPlayerConfig {
}

创建JavaConfig类的关键在于为其添加@Configuration注解,@Configuration注解表明这个类是一个配置类,该类应该包含在Spring应用上下文如何创建bean的细节。另外如果,我们将@ConfigurationScan这个注解移除掉,@Configuration定义的配置类就失去作用。

2.3.2声明简单的bean
要在JavaConfig中声明bean,我们需要编写一个方法,这个方法会创建所需类型的实例,然后给这个方法添加@Bean注解。bean的ID默认会和方法名一样,如果想取其他ID可以用bean的name属性:

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

//添加name属性
@Bean(name = "lonelyHeartClubBand")
public CompactDisc sgtPeppers(){
    return new SgtPeppers();
}

不管你用什么bean命名,bean的声明都非常简单。这里用Java描述,因此我们能够发挥Java的特性,这个方法,只要我们最后产生CompactDisc实例即可,至于具体是其他什么子对象都可以。

2.3.3 借助JavaConfig实现注入
我们前面所声明的CompactDisc bean是非常简单的,它自身没有其他的依赖。但现在我们要声明CDplayer bean ,它依赖CompactDisc。在JavaConfig中配置bean最简单方式就是引用创建bean的方法。例如,下面就是一种声明CDPlayer的可行方案:

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

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

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

因为通过调用方法来应用bean的方式令人困惑。还有一种更加简单的方式:


@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
return new CDPlayer(compactDisc);
}
在这里,CDPlayer()方法请求一个CompactDisc作为参数,当Spring调用cdPlayer()创建CDPlayer bean的时候,它会自动装配一个CompactDisc到配置方法中。而且不需要明确引用CompactDisc的@Bean方法。也不会要求将CompactDisc声明到同一个配置类中。它可以通过组件扫描、XML来进行配置。不管CompactDisc是采用什么方式创建出来的,Spring都会将其传入到配置方法中,并且用来创建CDPlayer bean。

2.4 通过XML装配Bean

在Spring刚刚出现的时候,,XML是描述配置的主要方式。尽管Spring长期以来确实与XML有着关联,但现在需要明确的是,XML不再是配置Spring的唯一可选方案。Spring有了强大的自动化配置和基于Java的配置,XML不应该再是你的第一选择。不过,鉴于已经存在那么多基于XML的Spring配置,所以理解如何在Spring中使用XML还是很重要的。
2.4.1 创建XML配置规范
在使用JavaConfig的时候,这意味着要创建一个带有@Configuration注解的类,而在XML配置中,这意味着要创建一个XML文件,并且要以元素为根。
最为简单的Spring配置如下所示:

<?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
     http://www.springframework.org/schema/context">

   <!--configuration detail go here -->
</beans>

在使用XML时,需要在配置文件的顶部声明多个XML模式(XSD)文件,这些文件定义了配置Spring的XML元素。用来装配bean的最基本的XML元素包含在spring-beans模式之中,在上面这个XML文件中,它被定义为根命名空间 。< beans>是该模式中的一个元素,它是所有Spring配置文件的根元素。

2.4.2 声明一个简单的bean
要在基于XML的Spring配置中声明一个bean,我们需要使用spring-beans模式中的另一个元素bean,bean元素类似于JavaConfig中@Bean注解,我们按照如下方式声明CompactDisc bean:

<bean class="soundsystem.SgtPeppers" />

这里声明了一个很简单的bean,创建这个bean的类通过class属性来指定,并且使用全限定的类名。因为没有给定明确的ID,所以这个bean将会根据全限定类名来进行命名。在本例中,这个bean的ID是“soundsystem.SgtPeppers#0”。其中“#0”是一个计数的形式,用来区分相同类型的其他bean。
尽管自动化的bean命名非常方便,但是当我们需要引用它时,自动命名的ID就没有我们自己手动设定来的方便。因此,我们最好借助id属性,为每个bean设置我们自己选择的名字:

<bean id="compactDisc" class="soundsystem.SgtPeppers" />

上面配置的bean中,当Spring发现这个bean元素时,它会调用SgtPeppers的默认构造函数来创建bean。

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

  • < constructor-arg>元素
  • 使用Spring3.0所引入的c-命名空间

两者的区别在很大程度就是是否冗长烦琐。另外,有些事情< construct-arg>可以做到,但是c-命名空间却无法实现。下面看两种方式的具体使用

构造器注入bean引用:
按照现在的定义,CDPlayer bean有一个接收CompactDisc类型的构造器。现在已经声明了SgtPeppers bean,并且SgtPeppers类实现了CompactDisc接口,所以我们已经有一个可以注入到CDPlayer bean中的bean。我们需要做的就是在XML中声明CDPlayer并通过ID引用SgtPeppers:

<bean id="cdPlayer" class="soundsystem.CDPlayer">
    <constructor-arg ref ="compactDisc" />
</bean>

当Spring遇到这个< bean>元素时,它会创建一个CDPlayer的实例。< constructor-arg>元素会告知Spring要将一个ID为compactDisc的bean引用传递到CDPlayer的构造器中。
作为代替的方案,我们也可以使用Spring的c-命名空间。c-命名空间实在Spring 3.0中引入的。要使用它,必须要在XML的顶部声明其模式,如下:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:c="http://www.springframework.org/schema/c"
   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">

   <!--configuration detail go here -->
</beans>

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

<bean id="cdPlayer" class="soundsystem.CDPlayer"
   c:cd-ref="compactDisc" />

属性名以“c:”开头,也就是命名空间的前缀。接下来就是要装配的构造器参数名,在此之后是“-ref”,这是一个命名约定,它会告诉Spring,正在装配的是一个bean的引用,这个bean的名字是compactDisc。
很显然,使用c-命名空间属性要比使用< constructor-arg>元素简练的多。

将字面量注入到构造器中:
迄今为止,我们所做的DI通常指的都是类型的装配–也就是将对象的引用装配到依赖它们的其他对象之中,有时候,我们需要做的只是用一个字面量值来配置对象,为了说明这一点,我们要创建一个CompactDisc的新的实现:

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.print("Playing "+title+" by "+artist);
   }
}

首先我们使用< constructor-arg>来实现一下:

<bean id ="compactDisc" class="soundsystem.BlankDisc">
    <constructor-arg value = "Sgt. Peppers's Lonely Hearts Club Band" />
    <constructor-arg value = "The Beatles" />
</bean>

然后用c-命名空间实现,方案一引用构造器参数的名字:

<bean id ="compactDisc" class="soundsystem.BlankDisc"
   c:_title = "Sgt. Peppers's Lonely Hearts Club Band"
   c:_artist="The Beatle" />

方案二,使用参数索引:

<bean id ="compactDisc" class="soundsystem.BlankDisc"
   c:_0 = "Sgt. Peppers's Lonely Hearts Club Band"
   c:_1 ="The Beatle" />

XML不允许某个元素的多个属性具有相同的名字。因此,如果有两个或更多的构造器参数的话,我们不能用简单的下划线来进行标识。

装配集合
目前为止,我们的CompactDisc在定义的时候只有唱片名称和艺术家的名字,实际的唱片中,一般都有十多个磁道,每个磁道上包含一首歌。所以,更新我们的BlankDisc:

package soundsystem;
import java.util.List;
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;
        this.tracks = tracks;
   }
   public void play(){
        System.out.print("Playing "+title+" by "+artist);
        for(String track:tracks){
           System.out.print("-Trakc: "+track);
        }
   }
}

此时,我们就需要使用到< list>元素,将其声明为一个列表:

<bean id ="compactDisc" class="soundsystem.BlankDisc">
    <constructor-arg value = "Sgt. Peppers's Lonely Hearts Club Band" />
    <constructor-arg value = "The Beatles" />
    <constructor-arg>
       <list>
           <value>Sgt. Peppers's Lonely Hearts Club Band</value>
           <value>With a Littile Help</value>
           <value>Luck in the Sky</value>
           <value>Getting Better</value>
           ...
       <list>
    </constructor-arg>
</bean>

其中< list>是< constructor-arg>的子元素,这表明一个包含值得列表将会传递到构造器中,其中< value>元素时用来指定列表中的每个元素。与之类似,我们可以使用< ref>元素代替< value>。如< ref bean=”sgtPeppers”>。同时,如果构造参数的类型是java.util.List时,我们可以使用< set>代替< list>。不同的是,set元素中重复的元素将会被忽略掉。

2.4.4 设置属性
到目前为止,CDPlayer和BlankDisc类完全是通过构造器注入的,没有使用属性的setter方法,接下来,我们看一下如何使用Spring XML实现属性注入:

public class CDPlayer implements MediaPlayer{
    private CompactDisc compactDisc;

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

作为一个通用的规则,我们倾向于对强依赖使用构造器注入,对于可选性的依赖使用属性注入。所以我们这里选择使用属性注入。使用如下:

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

< property>元素为属性Setter方法所提供的的功能与< constructor-arg>元素为构造器所提供的的功能是一样的。前面我们提到有与< constructor-arg>元素互为代替的c-命名空间的用法,与之类似,属性注入也提供了p-命名空间的用法来代替< property>,在XML中声明以及使用如下:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:p="http://www.springframework.org/schema/p"
   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">

   <!--configuration detail go here -->
   <!--装配compactDisc属性如下-->
   <bean id ="cdPlayer" class="soundsystem.CDPlayer"
       p:compactDisc-ref="compactDisc" />
</beans>

p-命名空间的命名约定规则如下:首先,属性的名字使用“p:”前缀,表明我们所设置的是一个属性。接下来就是要注入的属性名。最后,属性的名称已“-ref”结尾,这会提示Spring要进行装配的引用,而不是字面量。
将字面量注入到属性中:
上面我们说到,在CDPlayer中,有个方法setCompactDisc(),对应的参数是对象。现在,我们来看看如果在CDPlayer中,有个setTitle(String title);的方法,对应的参数是字符串,也就是字面量的时候,我们如何来做:

public class CDPlayer implements MediaPlayer{
    private String title;
    private List<String> tracks;

    public void setTitle(String title){
        this.title = title;
    }
    public void setTracks(List<String> tracks){
        this.tracks = tracks;
    }
    ...
<bean id="cdPlayer" class ="soundsystem.CDPlayer">
    <property name="title" value="Sgt. Peppers's Lonely Hearts Club Band"/>
    <property name="trakcs">
        <list>
        <value>Sgt. Peppers's Lonely Hearts Club Band</value>
        <value>With a Little Help from</value>
        <value>Luck in the Sky</value>
        </list>
    </property>
</bean>

还有另一种可选方案就是使用p-命名空间的属性来完成,即:

p:title="Sgt. Peppers's Lonely Hearts Club Band"

但是p-命名空间不能用来装配集合,没有便利的方式使用p-命名空间来指定一个值得列表。
但是我们可以使用Spring util-命名空间的一些功能来简化BlankDisc bean。首先声明util-命名空间及其模式:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:p="http://www.springframework.org/schema/p"
   xmlns:util="http://www.springframework.org/schema/util"
   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
     http://www.springframework.org/schema/util
     http://www.springframework.org/schema/util/spring-util.xsd">

   <!--configuration detail go here -->
   <!--装配compactDisc属性如下-->
   <bean id ="compactDisc" class="soundsystem.BlankDisc"
       p:title="Sgt. Peppers's Lonely Hearts Club Band"
       p:artist="The Beatles"
       p:tracks-ref="tracksList"/>

   <util:list id ="tracksList">
       <value>Sgt. Peppers's Lonely Hearts Club Band</value>
        <value>With a Little Help from</value>
        <value>Luck in the Sky</value>
   </util:list>
</beans>

2.5 导入和混合配置

在典型的Spring应用中,我们可能会同时使用自动化和显示配置,所以有时候JavaConfig、XML以及自动扫描混合在一起,在JavaConfig这种引用XML配置,可以去熟悉@Import注解,比如可以在一个配置类中引用另一个配置类:

@Configuration
@Import(anotherConfig.class)
public class Config{
   ....
}

如果是在一个配置类中,引用其他XML的配置,假设配置文件是cd-config.xml,可以使用:

@Configuration
@Import(anotherConfig.class)
@ImportResource("classpath:cd-config.xml")
public class Config{
   ....
}

另外,我们在一个XML文件中,引入另一个XML,我们也是使用< import>来引入文件如:

<import resoune="cd-config.xml">

如果是一个XML中需要引入JavaConfig呢?很简单,就是使用< bean>来直接引入

<bean class="soundsystem.Config" />

如果想将XML配置文件和JavaConfig文件组合到一起,我们可以定义一个根配置文件,然后使用< bean>和< import>来完成。同时不管是XML还是JavaConfig,我们可以在根配置文件中开启组件扫描通过< context:component-scan>或@ComponentScan来完成。

2.6 总结

Spring框架的核心就是Spring容器。容器负责管理应用中组件的生命周期,它会创建这些组件并保证它们的依赖得到满足,这样的话,组件才能完成预定任务。
在这个章节中,我们看到了在Spring中装配bean的三种方式:自动化装配、基于Java的显示配置以及基于XML的显示配置。不管采用什么方式,这些技术都描述了Spring应用中的组件以及这些组件之间的关系。
这是本人通过学习《Spring实战》第四版得到的笔记,因为之前也没有太多写笔记和博客的习惯,有写的不好的地方,欢迎大家指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值