Spring 装配Bean
一、Spring配置Bean的可选方案
- 隐式的bean发现机制和自动装配
- 在Java中显示配置
- 在XML文件中显示配置
二、自动化装配Bean
Spring实现自动化装配需要两个具体步骤
- 组件扫描(component scanning):Spring自动发现应用上下文中创建的bean
- 自动装配(autowiring):Spring自动满足bean之间的依赖
Spring通过注解来实现上面的两个功能
注解 | 功能 | 备注 |
---|---|---|
@Component | 声明组件,Spring为组件创建bean | Spring给此注解标记的bean默认ID为类名首字母小写,也可以通过参数指定(@Component(“myBean”)) |
@ComponmentScan | 开启Spring组件扫描 | 可通过basePackage或者basePackageClasses属性设置扫描的基础包 |
@AutoWired | 实现根据组件依赖自动装配 | 可用于构造器或者Setter方法甚至普通方法 |
说明:
1.组件扫描也可以使用XML文件开启: <context:componet-scan base-pakage="com.xinye.spring">
同时指定扫描的基础包名
2. @ComponentScan(basePackages={"xxx", "xxx"})
或者@ComponentScan(basePackagesClasses={xxx.class,xxx.class})
指定基础包,后者是类型安全的,因为重构代码时,会根据指定的类去寻找基础扫描包
3. java依赖注入规范(java Dependency Injection)中提供了类似@Component
以及@AutoWired
的两个注解,分别是@Named
和@Inject
,他们之间有细微差别,但是大多数情况可以相互替换
一个自动装配简单示例
接口和类
package soundSystem;
/*
**CD接口,有一个方法play()
*/
public interface CompactDisc {
public void play();
}
package soundSystem;
/**
* 媒体播放器接口,可以调用cd的play方法
*/
public interface MediaPlayer {
public void play();
}
package soundSystem;
import org.springframework.stereotype.Component;
/*一张cd继承自CompactDisk,有标题和艺术家两个属性*/
/*
@Componet 注解告知Spring为此类创建Bean
可以通过括号内添加id,默认为类名SgtPeppers首字母小写
* */
@Component("sgtPeppers")
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);
}
}
package soundSystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer implements MediaPlayer{
private CompactDisc cd;
/*constructor注入*/
@Autowired
public CDPlayer (CompactDisc cd){
this.cd = cd;
}
/*setter注入*/
@Autowired
public void setCompactDisc(CompactDisc cd){
this.cd = cd;
}
@Override
public void play(){
cd.play();
}
}
package soundSystem;
/*java Spring配置类*/
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
@Configuration注解标记Spring配置类
@ComponentScan启用组件扫描
或者通过xml配置启用组件扫描
<context:component-scan base-package="soundSystem">
*/
@Configuration
@ComponentScan
public class CDPlayerConfig {
}
测试类定义如下,@Contextconfiguration
注解传入Spring上下文的配置类或者xml文件名
package soundSystem;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDplayerTest {
@Rule
public final SystemOutRule rule = new SystemOutRule();
@Autowired
private CompactDisc cd;//通过spring自动装配
@Autowired
private MediaPlayer player;
@Test
public void cdShouldNotBeNull(){
assertNotNull(cd);
if(cd!=null)
System.out.println("cd is not null!");
}
@Test
public void play(){
player.play();
Assert.hasText(
"Playing Sgt. Pepper's Lonely Hearts Club Band" + " by The Beatles\n",
rule.getLog()
);
}
}
测试类中cd和player是通过自动扫描装配的,并且CDplayer中的cd成员变量也是自动装配的。
测试自动装配结果:
1.运行 cdShouldNotBeNull():
2.运行 play()