I. Spring Bean 的装配机制
在之前的章节里面我们讲过 Spring 的装配机制:
- 在 XML 中进行显式配置
- 通过 Annotation 在 Java 中进行隐式的 bean 发现机制和自动装配
Spring 提供了几种方式既可以单独使用,也可以配合着使用。即便如此,还是尽可能的使用自动装配的机制,显式的配置越少越好。
但是某些时候,比如模块有很多人开发,或者开发之后的源码由别人维护,配置 Bean 的时候,显式的配置则会更方便维护人员。那么除了 XML 的方式,我们还可以通过使用类型安全并且比 XML 更为强大的 JavaConfig来显式的配置 Bean。除非需要使用 XML 中的 namespace 并且 JavaConfig之中没有同样的实现的时候,就可以选择 XML 方式
II. Spring 自动化装配 Bean
之前的章节, Spring XML AutoWired 和 Spring Annotation 也介绍过如何使用注解和组件扫描来以及XML的方式实现自动化装配, 其实Spring是从两个角度来实现的自动化装配的:
组件扫描(component scanning): Spring 自动发现应用上下文所创建的 bean自动装配(autowiring): Spring 自动满足 bean 之间的依赖
那我们尽量使用组件扫描和自动装配来使得显式配置降低到最少, 下面通过一个实例来演示
III. 代码实例
我们来实现一个需求,创建一个 CD 播放器,播放器可以播放一张 CD,使用 Spring 来自动把 CD 装配给 CD 播放器。
我们先建立 CD 的概念,创建一个 CD 的接口,代码如下:
package org.lovian.spring.soundsystem;
/**
* Author: PENG Zhengshuai
* Date: 4/27/18
* lovian.org
*/
public interface CompactDisc {
void play();
}
在这个接口中,定义了一个 CD 播放器能够对一个 CD 所能进行的操作,然后我们创建一个 CD 的实现类,比如周杰伦的范特西,代码如下:
package org.lovian.spring.soundsystem;
import org.springframework.stereotype.Component;
/**
* Author: PENG Zhengshuai
* Date: 4/27/18
* lovian.org
*/
@Component
public class JayCompactDisc implements CompactDisc {
private String title = "Fantasy";
private String artist = "Jay Chou";
public void play() {
System.out.println("Playing " + title + " by " + artist);
}
}
在 JayCompactDisc 里面,我们定义了两个成员变量,调用 play() 方法时,会将这两个变量打印出来; 同时给这个类标注 @Component 注解,这个注解表明该类会作为一个组件类,并且告诉 Spring 在 IOC 容器中要去创建这个类的 bean 实例。
在 Spring Annotation 中我们讲到,由于组件扫描默认是不启用的,如果要使用组件扫描的功能,则需要在 XML 中配置 component-scan:
<context:component-scan base-package="org.lovian.spring.soundsystem">
在这里,我们还另一种 JavaConfig 的配置方式来配置组件扫描:
package org.lovian.spring.soundsystem;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* Author: PENG Zhengshuai
* Date: 4/27/18
* lovian.org
*/
@Configuration
@ComponentScan
public class CDPlayerConfig {
}
CDPlayerConfig 类通过代码的方式,完成了类似 XML 定义的装配规则。@Configuration 注解表明了这个类是一个配置类,而 @ComponentScan 注解则告诉 Spring 要启用组件扫描。
如果没有其他配置的话, Spring 会默认会扫描和标注了@ComponentScan 的配置类相同的包。在这里 CDPlayerConfig 位于包 org.lovian.spring.soundsystem 中,那么 Spring 则会扫描这个包以及其子包,查找所有被标注 @Component 注解的类,并为其创建 bean。
@ComponentScan也可以指定扫描的包,通过使用 basePackages 属性(注意是复数),可以指定多个包,用 ,分隔, 比如:
@ComponentScan(basePackages="org.lovian.spring.soundsystem", "org.lovian.spring.videos")
接下来我们创建一个 Test 类来测试一下结果
package org.lovian.spring.soundsystem;
import org.junit.Assert;
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;
/**
* Author: PENG Zhengshuai
* Date: 4/27/18
* lovian.org
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerTest {
@Autowired
private CompactDisc cd;
@Test
public void assertCdBean(){
Assert.assertNotNull(cd);
Assert.assertEquals(JayCompactDisc.class, cd.getClass());
}
}
这个类使用了 org.junit 库和 spring-test 模块,我们需要在 pom.xml 或者 classpath 中加入依赖,maven 依赖如下:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
在 CDPlayerTest 类中, @RunWith 是 Junit 组件的标注,SpringJUnit4ClassRunner 则是告诉 Junit,在测试开始的时候,调用这个类来自动创建 Spring 的 ApplicationContext。 @ContextConfiguration 注解则指明了要在哪个配置类中来加载配置。我们将 CompactDisc 使用 @Autowired 注解注入到这个 Test 类中,然后运行测试,测试通过。
Share this on