1

Spring 中装配 bean 的三种主要方式:

  • 自动化配置
  • 基于 Java 的显式配置
  • 基于 XML 的显式配置

自动化配置

建议尽可能使用自动化配置,以避免显式配置所带来的维护成本。
Spring 从两个角度来实现自动化装配:

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

创建可被发现的 bean

为了展示自动化配置,我们先定义一个CD的接口:

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

创建一个CD接口的实现类————SgtPeppers:

package com.soundsystem;  
  
import org.springframework.stereotype.Component;  
//@Componet("lonelyHeartsClub") 为bean明明,否则默认为sgtPeppers,也就是将类名的第一个字母变为小写。  
@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。没有必要显式配置 SgtPeppersbean,因为这个类使用了 @Component 注解,所以 Spring 会为你把事情处理妥当。

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

@ComponentScan 注解开启组件扫描,Spring 将会扫描这个包以及这个包下的所有子包,查找带有 @Component 注解的类,并为其创建 bean:

package com.soundsystem;  
  
import org.springframework.context.annotation.\*;
@Configuration//表明这个类是一个配置类
@ComponentScan//
public class CDPlayerConfig {
}

为组件扫描命名

如果没有为bean显示命名,否则默认为sgtPeppers,也就是将类名的第一个字母变为小写。

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

设置组件扫描的基础包

开启组件扫描,Spring 将会默认扫描这个包以及这个包下的所有子包。
可以用basePackages属性指定包名:

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

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

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

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

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

比方说,将唱片注入播放器:

package com.soundsystem;  
  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.beans.factory.annotation.Value;  
import org.springframework.stereotype.Component;~~~~
@Component  
public class CDPlayer implements MediaPlayer {  
  
  private CompactDisc cd;  
  
  @Autowired(required = false)  
  public CDPlayer(CompactDisc cd){  
        this.cd = cd;  
  }  
  public void play() {  
  }  
}

它的构造器上添加了 @Autowired 注解,这表明当 Spring 创建 CDPlayerbean 的时候,会通过这个构造器来进行实例化并且会传入一个可设置给 CompactDisc 类型的 bean,将一个 CompactDisc 注入到 CDPlayer 之中。
如果没有匹配的 bean,那么在应用上下文创建的时候,Spring 会抛出 一个异常。为了避免异常的出现,你可以将 @Autowired 的 required 属性设置为 false。

如果有多个 bean 都能满足依赖关系的话,Spring 将会抛出一个异常,表明没有明确指定要选择哪个 bean 进行自动装配。

通过 Java 代码装配 bean

有些时候你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加 @Component 和 @Autowired 注解的,因此就不能使用自动化装配的方案了。

创建配置类

@Configuration//表明这个类是一个配置类    
public class CDPlayerConfig {  

}

声明bean

@Configuration//表明这个类是一个配置类    
public class CDPlayerConfig {  
    //@Bean(name="lonelyHeartsClubBand")这样可以给bean显示命名 
    @Bean
    public CompactDisc sgtPeppers(){  
        return new SgtPeppers();  
    }
}

@Bean这表明这个方法会创建一个 bean 实例并将其注册到 Spring 应用上下文中。

实现注入

@Configuration//表明这个类是一个配置类    
public class CDPlayerConfig {  
    //@Bean(name="lonelyHeartsClubBand")这样可以给bean显示命名 
    @Bean
    public CompactDisc sgtPeppers(){  
        return new SgtPeppers();  
    }
    //将CompactDisc 注入到 CDPlayer 之中
    @Bean  
    public CDPlayer cdPlayer(){  
        return new CDPlayer(sgtPeppers());  
    }
}

通过 XML 装配 bean

这只是用来帮助你维护已有的 XML 配置,在完成新的 Spring 工作时,希望你会使用自动化配置和 JavaConfig。

创建XML配置规范

使用idea新建XML Spring Congfig配置文件即可。

声明一个简单的<bean>

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

创建这个 bean 的类通过 class 属性来指定的,并且要使用全限定的类名。
借助id属性,为bean命名。

借助构造器注入初始化 bean

构造器注入 bean 引用

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

将字面量注入到构造器中

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

装配集合

<bean id="compactDisc" class="com.soundsystem.BlankDisc">  
    <constructor-arg index="0" value="Sgt. Pepper's Lonely Hearts Club Band"/>  
    <constructor-arg index="1" value="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 引用列表的装配 --> 
    <constructor-arg>  
        <list>  
            <ref bean="compactDisc" />  
        </list>  
    </constructor-arg>  
</bean>

导入和混合配置

将一个JavaConfig配置中拆成多个

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

使用@Import注解导入DConfig.class配置:

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

在 JavaConfig 中引用 XML 配置

使用@ImportResource("classpath:"):

@Configuration
@Import(CDConfig.class)  
@ImportResource("classpath:")
public class CDPlayerConfig {  
    @Bean  
  public CDPlayer cdPlayer(CompactDisc compactDisc){  
        return new CDPlayer(compactDisc);  
    }  
}

在 XML 配置中引用 JavaConfig

<?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">

<!--导入javaConfig配置-->
<bean class="com.soundsystem.CDPlayerConfig" />
<!--导入其他xml配置-->
<import resource="cdplayer-config.xml"  />

</beans>

WinRT
21 声望4 粉丝

临渊羡鱼,不如退而结网


« 上一篇
Spring核心
下一篇 »
Spring高级装配