装配Bean
1. 在Spring中,对象不用自己查找或者创建与其所关联的其他对象。Spring容器会负责把需要相互协作的对象引用赋予各个对象。例如:一个订单管理组件需要信用卡认证组件,但它不需要自己创建信用卡认证组件。订单管理组件只需要表明自己两手空空,容器就会主动赋予它一个信用卡认证组件。
2. 创建应用对象的之间的协作关系的行为通常称为装配(wiring),这也是依赖注入(DI)的本质。
2.1 Spring配置的可选方案
Spring提供了三种主要的装配机制:
-
在XML中进行显示的配置
-
在Java中进行显示的配置
-
隐式bean发现机制和自动装配
2.2 自动化装配bean
Spring的自动化配置提供了非常大的便利性。问题:如果Spring能够进行自动化配置,那为什么我们还要显式的将这些bean装配在一起呢?
Spring从两个角度来实现自动化装配:
-
组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
-
自动装配(autowiring):Spring自动满足bean之间的依赖。
组件扫描和自动装配组合在一起就能发挥强大的威力,它们能够将你的显示配置降低到最少。
2.2.1 创建可被发现的bean
我们先来创建几个Bean,它们代表一个音响系统中的组件。创建CompactDisc类,CDplayer类。我们需要让Spring发现CompactDisc为它创建一个bean,然后Spring把CompactDisc的bean注入到CDPlayer中。
1.先定义一个CD的一个接口
package com.xuefei.spring_pro.cdDemo; /** * * @author 雪飞oubai * cd接口 */ public interface CompactDisc { public void play(); }
CompactDisc的具体内容并不重要,重要的是你将其定义为一个接口。作为接口,它定义了CD播放器对一盘CD所能进行的操作。它将CD播放器的任意实现与CD本身的耦合降低到了最小的程度。
2.再来一个CompactDisc的实现
package com.xuefei.spring_pro.cdDemo; import org.springframework.stereotype.Component; /** * * SgtPappers实现CompactDisc接口 * * @Component注解表明该类会作为组件类,并告知Spring要为这个类创建bean * 但是组件扫描默认是不开启的,还需要显式的配置一下Spring */ @Component public class SgtPeppers implements CompactDisc{ private String title = "Sggt.Papper's Lonely Hearts Club Band"; private String artist = "The Beatles"; @Override public void play() { System.out.println("Playing " + title + "by " + artist); } }
3.显示配置一下Spring让其开启组件扫描(两种方式)
1. 通过@ComponentScan注解开启组件扫描
package com.xuefei.spring_pro.cdDemo; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * * @author 雪飞oubai * 使用@ComponentScan默认会扫描与配置类相同的包,查找带有@Component注解的类 * 这样Spring就可以为其创建Bean */ @Configuration @ComponentScan public class CDPlayConfig { }
2. 使用XML启用组件扫描(在配置文件中加上这样一段代码)
<context:component-scan base-package="com.xuefei.spring_pro.cdDemo"> </context:component-scan>
5. 创建一个简单的Junit测试
package com.xuefei.spring_pro.test; import static org.junit.Assert.assertNotNull; 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; import com.xuefei.spring_pro.cdDemo.CDPlayConfig; import com.xuefei.spring_pro.cdDemo.CompactDisc; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CDPlayConfig.class) public class CDPlayTest { @Autowired private CompactDisc cd; @Test public void cdShouldNotBeNull() { cd.play(); assertNotNull(cd); } }
CDPalyerTest使用了SpringJunit4ClassRunner,以便在测试开始的时候自动创建Spring的应用上下文,注解@ContextConfiguration会告诉它需要在CDPlayConfig中加载配置。因为CDPlayConfig类中包含了@ComponentScan,因此最终的应用上下文中应该包含CompactDisc bean