Spring in action 01 -- 装配 Bean(@Autowired)

来源:互联网 发布:火线精英软件免费版 编辑:程序博客网 时间:2024/06/06 06:57

昨天走马观花,看一遍Spring,当然也比较的片面,今天就从第一个知识点详细些再学习。温故而知新,可以为师也,如此而而

一个概念 装配(wiring) : 创建应用对象之间协作关系的行为通常称为装配。它是DI的本质,而DI是Spring的最基本要素。

三种装配机制:

  • 在XML中进行显式配置
  • 在Java中进行显式配置
  • 隐式的bean发现机制和自动装配

根据项目的需要,你可以选择一种方式,也可以选择多种进行混合搭配。大牛们建议使用自动装配。显式配置越少越好,所以我从后往前看,先看 隐式bean发现机制和自动装配

目录结构及说明:

这里写图片描述

接口类 CompactDisc.java:

这里写图片描述

实现类 SgtPeppers.java

这里写图片描述

配置类 CDPlayerConfig.java

这里写图片描述

这里没有显式的在XML文件中去配置,那么现在在Spring的应用上下文中已经有了 SgtPeppers bean.所有带有@Component 注解的类都会被创建为bean。写一个Junit测试类测试一下:

这里写图片描述

说明一下:

SpringJUnit4ClassRunner–在测试开始的时候自动创建一个Spring 应用上下文;
@ContextConfiguration–告诉你要在目标class中加载配置;
@Autowired–把目标bean自动装配进去。

里面用到的spring-test要去Maven里去下载:

这里写图片描述

总之最终的结果是可以看到绿条了。说明目标bean已经在Spring的应用上下文中了。

note: 上面添加@Component的bean,没有给它命名,在这种情况下呢,Spring会根据类名为其指定一个ID,即类名第一个字母小写。当然了,可以自己命名,像参数一样传递给@Component,像下面这样:

@Component("lonelyHeartsClub")public class SgtPeppers implements CompactDisc{    ...}

接下来看@ComponentScan

上面的示例中我没有为@ComponentScan注解添加任何属性,那么此时它会以配置类所在的包为basePackage去扫描组件,如果要扫描其他你想要的包,应该这么做:

@Configuration@ComponentScan(basePackages={"soundsystem","otherpackage"})public class CDPlayerConfig{    ...}

在basePackage中包名是以String形式表示的,作者说是not type-safe的,如若重构代码的话,那么所指定的basePackage可能就会出错。所以就会有另外一种形式:

@Configuration@ComponentScan(basePackageClasses={CDPlayer.class, DVDPlayer.class})public class CDPlayerConfig{    ...}

那么这个时候,上面的这些类所在的包就会作为组件扫描的basePackage。

接下来看@Autowired

在项目中一般都是很多的对象依赖其他的对象来完成相应的task,那么需要有一种方法能够将组件扫描得到的bean与它们的依赖装配在一起。所以就可以借助Spring的@Autowired 注解。

  • 可以使用在构造器、setter方法以及普通方法上
    我觉得没有太多需要解释的,就像下面这样:
@Componentpublic class CDPlayer implements CompactDisc{    private CompactDisc cd;    @Autowired    public CDPlayer(CompactDisc cd){        this.cd = cd;    }    public void play(){        ...    }}

我在构造器中添加了@Autowired 注解,当Spring创建CDPlayer bean时,会通过该构造器进行实例化并且传一个可设置给CompactDisc类型的bean. 在setter()方法和其他普通方法上是一样的。如此而而

note: 若只有一个bean 匹配的话,很理想;若是没有对应的bean,可以这样设置:将@Autowired的required属性设置为false :

@Autowired(required=false)

作者说如果在代码中没有进行null检查的话,这个处于未装配状态的属性有可能会出现NullPointerException。

若是有多个对应的bean时,又会出现什么的情况呢,后面再分析 。

先对上面的自动装配作一个测试:准备好所要用到的类
接口类:MediaPlayer.java

package com.stanxu.soundsystem;public interface MediaPlayer {    void play();}

需要测试的类:CDPlayer.java

package com.stanxu.soundsystem;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;@Componentpublic class CDPlayer implements MediaPlayer {    private CompactDisc cd;    @Autowired    public CDPlayer(CompactDisc cd) {        // TODO Auto-generated constructor stub        this.cd = cd;    }    public void play(){        cd.play();    }}

在CDPlayer的构造器中添加了@Autowired注解,Spring将把一个可分配给CompactDisc类型的bean自动注入进来,来验证这一点

package com.stanxu.soundsystem;import org.junit.Rule;import org.junit.Test;import static org.junit.Assert.*;import org.junit.contrib.java.lang.system.StandardOutputStreamLog;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)@ContextConfiguration(classes=CDPlayerConfig.class)public class CDPlayerTest {    @Rule    public final StandardOutputStreamLog log = new StandardOutputStreamLog();    @Autowired    private MediaPlayer player;    @Autowired    private CompactDisc disc;    @Test    public void cdShouldNotBeNull(){        assertNotNull(disc);    }    @Test    public void play(){        player.play();        assertEquals("Playing Sgt. Pepper's Lonely Hearts Club Band by The Beatles", log.getLog());    }}

可以看到绿条了:

这里写图片描述

这里我们用到这个注解@Rule,以及它注解下的StandardOutputStreamLog,那么它是一个来源于System Rules库的一个JUnit规则,有些类似于System.out.print(),这里我在play()方法里断言 SgtPeppers.play()方法被输出到了控制台上,所以为了用上面的@Rule注解,我们要去Maven仓库中下载:http://mvnrepository.com/artifact/com.github.stefanbirkner/system-rules/1.2.0

这里写图片描述

0 0
原创粉丝点击