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:
@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 注解。
比方说,将唱片注入播放器:
@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 的类通过 class 属性来指定的,并且要使用全限定的类名。
借助id属性,为bean命名。
借助构造器注入初始化 bean
构造器注入 bean 引用
将字面量注入到构造器中
装配集合
Sgt. Pepper's Lonely Hearts Club Band
With a Little Help from My Friends
Lucy in the Sky with Diamonds
Getting Better
Fixing a Hole
导入和混合配置
将一个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