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>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。