【Spring实战】第2章 装配Bean
组件扫描
使用 <bean>
标签一个个将类定义到配置文件很麻烦,可以启用组件扫描,自动扫描类注册到上下文中。
@Component
:哪些类是要扫描的
/**
* 如果启用了组件自动扫描,这个注解就是告诉 Spring 要创建 Bean。
* 在 Spring 的上下文中有一个 Bean ID,默认是类名首字母小写,如 sgtPeppers。
* 使用 @Component("newName") 配置自定义的新名字
*/
@Component
public class SgtPeppers implements CompactDisc {}
如果接口 CompactDisc 的实现类有 2 个,那么 @Autowire 的时候怎么判断要用哪个呢?
使用 @Component("newName") 自定义名字,然后使用 @Autowired 和 @Qualifier("newName") 来指定。
@ComponentScan
:启动组件扫描
/*
@ComponentScan 默认扫描配置类所在的包。
使用 @ComponentScan(basePackages = "soundsystem") 可以扫描指定包。还可以指定类所在的包。
*/
@Configuration
@ComponentScan(basePackages = "soundsystem")
public class CDPlayerConfig {
}
或者在 XML 文件里面启动:
<context:component-scan base-package="soundsystem"/>
Spring Test 自动创建上下文
如果只用 Junit,每次创建测试类,都要 new 上下文,很麻烦。使用 SpringTest 自动创建上下文。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.0.7.RELEASE</version>
</dependency>
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) // 自动创建 Spring 应用上下文
@ContextConfiguration(classes = CDPlayerConfig.class) // 到 CDPlayerConfig 加载配置
public class AutoScanTest {
@Autowired
private CompactDisc cd;
@Test
public void test1() {
cd.play();
}
}
自动装配
@Component
public class CDPlayer implements MediaPlayer {
private CompactDisc cd;
/*
表明 Spring 创建 CDPlayer 时,会使用这个构造器。
不论是构造器,还是 Setter,Spring 都会尝试满足方法上的参数依赖,将 Bean 装配进来。
如果没有匹配的 Bean,会抛异常,可使用 @Autowired(required = false)
*/
@Autowired
public CDPlayer(CompactDisc cd) {
this.cd = cd;
}
@Autowired
public void setCompactDisc(CompactDisc cd) {
this.cd = cd;
}
public void play() {
cd.play();
}
}
Java 装配 Bean
@Configuration
@ComponentScan
public class CDPlayerConfig {
/*
要将第三方的组件装配到应用中
@Bean(name="newName") 指定名字
*/
@Bean
public CompactDisc sgtPeppers() {
return new SgtPeppers();
}
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {
// 可以通过构造器或 Setter 方法注入依赖
CDPlayer cdPlayer = new CDPlayer(compactDisc);
cdPlayer.setCompactDisc(compactDisc);
return cdPlayer;
}
}
使用 XML 装配 Bean
<?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:context="http://www.springframework.org/schema/context"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
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/beans/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
@ContextConfiguration(locations = {"classpath*:/soundsystem.xml"}) // classpath* 指在 classpath 和 jar 包中找
构造器注入
<!-- 使用 c 命名空间,c:_0 表示第一个参数的值
<bean id="compactDisc" class="soundsystem.BlankDisc" c:_0="qiqi" c:_1="caca">
<constructor-arg>
<list>
<value>v1</value>
<value>v2</value>
</list>
</constructor-arg>
</bean>-->
<bean id="compactDisc" class="soundsystem.BlankDisc">
<constructor-arg value="haha"/>
<constructor-arg value="xixi"/>
<!-- 参数类型是 List<String>,将列表设置为 null
<constructor-arg><null/></constructor-arg>-->
<constructor-arg>
<!-- 还有 <Set> 标签 -->
<list>
<value>v1</value>
<value>v2</value>
<!-- 类型是 List<Bean>,要实现 Bean 引用列表的装配
<ref bean="sgtPeppers"/>
-->
</list>
</constructor-arg>
</bean>
<!-- c:_0-ref 表示第一个参数 -->
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_0-ref="compactDisc"/>
Setter 注入
<bean id="cdPlayer" class="soundsystem.CDPlayer" p:compactDisc-ref="compactDisc"/>
<!--<bean id="compactDisc" class="soundsystem.BlankDisc">
<property name="title" value="haha"/>
<property name="tracks">
<list>
<value>v1</value>
<value>v2</value>
</list>
</property>
</bean>-->
<bean id="compactDisc" class="soundsystem.BlankDisc" p:title="haha" p:tracks-ref="trackList"/>
<!-- 使用 util 命令来简化列表-->
<util:list id="trackList">
<value>v1</value>
<value>v2</value>
</util:list>
将配置组合起来
@Configuration
@Import(CDConfig.class)
@ImportResource("classpath:cd-config.xml")
<bean class="soundsystem.CDConfig"/>
<import resource="soundsystem.xml"/>